From ec48a014e27569ec7e8d185c5fa21c9e14b281c7 Mon Sep 17 00:00:00 2001 From: Alessio Attilio Date: Mon, 1 Jun 2026 20:23:13 +0200 Subject: [PATCH 1/3] fix(db): add manual migration from 38 to 37 to prevent data loss on downgrade --- .../com/metrolist/music/db/MusicDatabase.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/app/src/main/kotlin/com/metrolist/music/db/MusicDatabase.kt b/app/src/main/kotlin/com/metrolist/music/db/MusicDatabase.kt index d73d34e227..099bc4485f 100644 --- a/app/src/main/kotlin/com/metrolist/music/db/MusicDatabase.kt +++ b/app/src/main/kotlin/com/metrolist/music/db/MusicDatabase.kt @@ -177,6 +177,7 @@ abstract class InternalDatabase : RoomDatabase() { MIGRATION_21_24, MIGRATION_22_24, MIGRATION_24_25, + MIGRATION_38_37, ).fallbackToDestructiveMigration(dropAllTables = true) .setJournalMode(RoomDatabase.JournalMode.WRITE_AHEAD_LOGGING) .setTransactionExecutor( @@ -813,6 +814,21 @@ val MIGRATION_24_25 = } } +val MIGRATION_38_37 = + object : Migration(38, 37) { + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL("DROP TABLE IF EXISTS `ArtistPageCache`") + db.execSQL( + "CREATE TABLE IF NOT EXISTS `artist_new` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `thumbnailUrl` TEXT, `channelId` TEXT, `lastUpdateTime` INTEGER NOT NULL, `bookmarkedAt` INTEGER, `isLocal` INTEGER NOT NULL DEFAULT false, `isPodcastChannel` INTEGER NOT NULL DEFAULT false, PRIMARY KEY(`id`))" + ) + db.execSQL( + "INSERT INTO `artist_new` (`id`, `name`, `thumbnailUrl`, `channelId`, `lastUpdateTime`, `bookmarkedAt`, `isLocal`, `isPodcastChannel`) SELECT `id`, `name`, `thumbnailUrl`, `channelId`, `lastUpdateTime`, `bookmarkedAt`, `isLocal`, `isPodcastChannel` FROM `artist`" + ) + db.execSQL("DROP TABLE `artist`") + db.execSQL("ALTER TABLE `artist_new` RENAME TO `artist`") + } + } + class Migration29To30 : AutoMigrationSpec { override fun onPostMigrate(db: SupportSQLiteDatabase) { // Ensure isVideo column exists (safeguard) From 6eae1c5a29341ba009b6c41854b477db2f71d5a7 Mon Sep 17 00:00:00 2001 From: Alessio Attilio Date: Mon, 1 Jun 2026 20:32:36 +0200 Subject: [PATCH 2/3] fix(di): correctly inject MusicDatabase instance to ensure migrations execute --- .../kotlin/com/metrolist/music/db/MusicDatabase.kt | 2 +- .../main/kotlin/com/metrolist/music/di/AppModule.kt | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/src/main/kotlin/com/metrolist/music/db/MusicDatabase.kt b/app/src/main/kotlin/com/metrolist/music/db/MusicDatabase.kt index 099bc4485f..d0007cb2c3 100644 --- a/app/src/main/kotlin/com/metrolist/music/db/MusicDatabase.kt +++ b/app/src/main/kotlin/com/metrolist/music/db/MusicDatabase.kt @@ -54,7 +54,7 @@ import java.util.Date import java.util.Locale class MusicDatabase( - private val delegate: InternalDatabase, + val delegate: InternalDatabase, ) : DatabaseDao by delegate.dao { val speedDialDao: SpeedDialDao get() = delegate.speedDialDao diff --git a/app/src/main/kotlin/com/metrolist/music/di/AppModule.kt b/app/src/main/kotlin/com/metrolist/music/di/AppModule.kt index f0fe16e9b1..b711d78f1e 100644 --- a/app/src/main/kotlin/com/metrolist/music/di/AppModule.kt +++ b/app/src/main/kotlin/com/metrolist/music/di/AppModule.kt @@ -48,17 +48,15 @@ object AppModule { @Singleton @Provides - fun provideInternalDatabase( + fun provideDatabase( @ApplicationContext context: Context, - ): InternalDatabase = Room - .databaseBuilder(context, InternalDatabase::class.java, InternalDatabase.DB_NAME) - .build() + ): MusicDatabase = InternalDatabase.newInstance(context) @Singleton @Provides - fun provideDatabase( - internalDatabase: InternalDatabase, - ): MusicDatabase = MusicDatabase(internalDatabase) + fun provideInternalDatabase( + database: MusicDatabase, + ): InternalDatabase = database.delegate @Singleton @Provides From b3c312077e03f9ef087349a089b76500eedcb9f7 Mon Sep 17 00:00:00 2001 From: Alessio Attilio Date: Mon, 1 Jun 2026 20:33:28 +0200 Subject: [PATCH 3/3] fix(db): use DEFAULT 0 instead of DEFAULT false for sqlite compatibility --- app/src/main/kotlin/com/metrolist/music/db/MusicDatabase.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/metrolist/music/db/MusicDatabase.kt b/app/src/main/kotlin/com/metrolist/music/db/MusicDatabase.kt index d0007cb2c3..a344740d2f 100644 --- a/app/src/main/kotlin/com/metrolist/music/db/MusicDatabase.kt +++ b/app/src/main/kotlin/com/metrolist/music/db/MusicDatabase.kt @@ -819,7 +819,7 @@ val MIGRATION_38_37 = override fun migrate(db: SupportSQLiteDatabase) { db.execSQL("DROP TABLE IF EXISTS `ArtistPageCache`") db.execSQL( - "CREATE TABLE IF NOT EXISTS `artist_new` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `thumbnailUrl` TEXT, `channelId` TEXT, `lastUpdateTime` INTEGER NOT NULL, `bookmarkedAt` INTEGER, `isLocal` INTEGER NOT NULL DEFAULT false, `isPodcastChannel` INTEGER NOT NULL DEFAULT false, PRIMARY KEY(`id`))" + "CREATE TABLE IF NOT EXISTS `artist_new` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `thumbnailUrl` TEXT, `channelId` TEXT, `lastUpdateTime` INTEGER NOT NULL, `bookmarkedAt` INTEGER, `isLocal` INTEGER NOT NULL DEFAULT 0, `isPodcastChannel` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`id`))" ) db.execSQL( "INSERT INTO `artist_new` (`id`, `name`, `thumbnailUrl`, `channelId`, `lastUpdateTime`, `bookmarkedAt`, `isLocal`, `isPodcastChannel`) SELECT `id`, `name`, `thumbnailUrl`, `channelId`, `lastUpdateTime`, `bookmarkedAt`, `isLocal`, `isPodcastChannel` FROM `artist`"