diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/adapters/ServerRowAdapter.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/adapters/ServerRowAdapter.kt index 89c7a5ea..8790bf7c 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/adapters/ServerRowAdapter.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/adapters/ServerRowAdapter.kt @@ -1,4 +1,4 @@ -package org.moire.ultrasonic.fragment +package org.moire.ultrasonic.adapters import android.content.Context import android.graphics.drawable.Drawable diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ActiveServerProvider.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ActiveServerProvider.kt index be4af76f..e132c67f 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ActiveServerProvider.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ActiveServerProvider.kt @@ -19,8 +19,6 @@ import timber.log.Timber /** * This class can be used to retrieve the properties of the Active Server * It caches the settings read up from the DB to improve performance. - * - * TODO: There seems to be some confusion whether offline id is 0 or -1. Clean this up (carefully!) */ class ActiveServerProvider( private val repository: ServerSettingDao @@ -35,7 +33,7 @@ class ActiveServerProvider( */ @JvmOverloads fun getActiveServer(serverId: Int = getActiveServerId()): ServerSetting { - if (serverId > 0) { + if (serverId > OFFLINE_DB_ID) { if (cachedServer != null && cachedServer!!.id == serverId) return cachedServer!! // Ideally this is the only call where we block the thread while using the repository @@ -53,22 +51,11 @@ class ActiveServerProvider( return cachedServer!! } - setActiveServerId(0) + // Fallback to Offline + setActiveServerId(OFFLINE_DB_ID) } - return ServerSetting( - id = -1, - index = 0, - name = UApp.applicationContext().getString(R.string.main_offline), - url = "http://localhost", - userName = "", - password = "", - jukeboxByDefault = false, - allowSelfSignedCertificate = false, - ldapSupport = false, - musicFolderId = "", - minimumApiVersion = null - ) + return OFFLINE_DB } /** @@ -77,9 +64,9 @@ class ActiveServerProvider( */ fun setActiveServerByIndex(index: Int) { Timber.d("setActiveServerByIndex $index") - if (index < 1) { + if (index <= OFFLINE_DB_INDEX) { // Offline mode is selected - setActiveServerId(0) + setActiveServerId(OFFLINE_DB_ID) return } @@ -103,22 +90,20 @@ class ActiveServerProvider( Timber.i("Switching to new database, id:$activeServer") cachedServerId = activeServer - return Room.databaseBuilder( - UApp.applicationContext(), - MetaDatabase::class.java, - METADATA_DB + cachedServerId - ) - .fallbackToDestructiveMigrationOnDowngrade() - .build() + return buildDatabase(cachedServerId) } val offlineMetaDatabase: MetaDatabase by lazy { - Room.databaseBuilder( + buildDatabase(OFFLINE_DB_ID) + } + + private fun buildDatabase(id: Int?): MetaDatabase { + return Room.databaseBuilder( UApp.applicationContext(), MetaDatabase::class.java, - METADATA_DB + 0 + METADATA_DB + id ) - .fallbackToDestructiveMigrationOnDowngrade() + .fallbackToDestructiveMigration() .build() } @@ -177,8 +162,24 @@ class ActiveServerProvider( } companion object { - const val METADATA_DB = "$DB_FILENAME-meta-" + const val OFFLINE_DB_ID = -1 + const val OFFLINE_DB_INDEX = 0 + + val OFFLINE_DB = ServerSetting( + id = OFFLINE_DB_ID, + index = OFFLINE_DB_INDEX, + name = UApp.applicationContext().getString(R.string.main_offline), + url = "http://localhost", + userName = "", + password = "", + jukeboxByDefault = false, + allowSelfSignedCertificate = false, + ldapSupport = false, + musicFolderId = "", + minimumApiVersion = null + ) + val liveActiveServerId: MutableLiveData = MutableLiveData(getActiveServerId()) /** @@ -186,7 +187,7 @@ class ActiveServerProvider( * @return True, if the "Offline" mode is selected */ fun isOffline(): Boolean { - return getActiveServerId() < 1 + return getActiveServerId() == OFFLINE_DB_ID } /** diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/AppDatabase.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/AppDatabase.kt index 2eecb7d7..125f9a31 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/AppDatabase.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/AppDatabase.kt @@ -9,7 +9,11 @@ import androidx.sqlite.db.SupportSQLiteDatabase * Room Database to be used to store global data for the whole app. * This could be settings or data that are not specific to any remote music database */ -@Database(entities = [ServerSetting::class], version = 4) +@Database( + entities = [ServerSetting::class], + version = 4, + exportSchema = true +) abstract class AppDatabase : RoomDatabase() { /** @@ -175,3 +179,89 @@ val MIGRATION_4_3: Migration = object : Migration(4, 3) { ) } } + +val MIGRATION_4_5: Migration = object : Migration(4, 5) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL( + """ + CREATE TABLE IF NOT EXISTS `_new_ServerSetting` ( + `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + `index` INTEGER NOT NULL, + `name` TEXT NOT NULL, + `url` TEXT NOT NULL, + `color` INTEGER, + `userName` TEXT NOT NULL, + `password` TEXT NOT NULL, + `jukeboxByDefault` INTEGER NOT NULL, + `allowSelfSignedCertificate` INTEGER NOT NULL, + `ldapSupport` INTEGER NOT NULL, + `musicFolderId` TEXT, + `minimumApiVersion` TEXT, + `chatSupport` INTEGER, + `bookmarkSupport` INTEGER, + `shareSupport` INTEGER, + `podcastSupport` INTEGER + ) + """.trimIndent() + ) + database.execSQL( + """ + INSERT INTO `_new_ServerSetting` ( + `ldapSupport`,`musicFolderId`,`color`,`index`,`userName`,`minimumApiVersion`, + `jukeboxByDefault`,`url`,`password`,`shareSupport`,`bookmarkSupport`,`name`, + `podcastSupport`,`id`,`allowSelfSignedCertificate`,`chatSupport` + ) + SELECT `ldapSupport`,`musicFolderId`,`color`,`index`,`userName`, + `minimumApiVersion`,`jukeboxByDefault`,`url`,`password`,`shareSupport`, + `bookmarkSupport`,`name`,`podcastSupport`,`id`,`allowSelfSignedCertificate`, + `chatSupport` + FROM `ServerSetting` + """.trimIndent() + ) + database.execSQL("DROP TABLE `ServerSetting`") + database.execSQL("ALTER TABLE `_new_ServerSetting` RENAME TO `ServerSetting`") + } +} + +val MIGRATION_5_4: Migration = object : Migration(5, 4) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL( + """ + CREATE TABLE IF NOT EXISTS `_new_ServerSetting` ( + `id` INTEGER PRIMARY KEY NOT NULL, + `index` INTEGER NOT NULL, + `name` TEXT NOT NULL, + `url` TEXT NOT NULL, + `color` INTEGER, + `userName` TEXT NOT NULL, + `password` TEXT NOT NULL, + `jukeboxByDefault` INTEGER NOT NULL, + `allowSelfSignedCertificate` INTEGER NOT NULL, + `ldapSupport` INTEGER NOT NULL, + `musicFolderId` TEXT, + `minimumApiVersion` TEXT, + `chatSupport` INTEGER, + `bookmarkSupport` INTEGER, + `shareSupport` INTEGER, + `podcastSupport` INTEGER + ) + """.trimIndent() + ) + database.execSQL( + """ + INSERT INTO `_new_ServerSetting` ( + `ldapSupport`,`musicFolderId`,`color`,`index`,`userName`,`minimumApiVersion`, + `jukeboxByDefault`,`url`,`password`,`shareSupport`,`bookmarkSupport`,`name`, + `podcastSupport`,`id`,`allowSelfSignedCertificate`,`chatSupport` + ) + SELECT `ldapSupport`,`musicFolderId`,`color`,`index`,`userName`, + `minimumApiVersion`,`jukeboxByDefault`,`url`,`password`,`shareSupport`, + `bookmarkSupport`,`name`,`podcastSupport`,`id`,`allowSelfSignedCertificate`, + `chatSupport` + FROM `ServerSetting` + """.trimIndent() + ) + database.execSQL("DROP TABLE `ServerSetting`") + database.execSQL("ALTER TABLE `_new_ServerSetting` RENAME TO `ServerSetting`") + } +} diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ServerSetting.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ServerSetting.kt index e3fb9b04..e3bf722c 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ServerSetting.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/data/ServerSetting.kt @@ -39,7 +39,4 @@ data class ServerSetting( constructor() : this ( -1, 0, "", "", null, "", "", false, false, false, null, null ) - constructor(name: String, url: String) : this( - -1, 0, name, url, null, "", "", false, false, false, null, null - ) } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/AppPermanentStorageModule.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/AppPermanentStorageModule.kt index adce9869..fcbc0f58 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/AppPermanentStorageModule.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/AppPermanentStorageModule.kt @@ -12,6 +12,8 @@ import org.moire.ultrasonic.data.MIGRATION_2_3 import org.moire.ultrasonic.data.MIGRATION_3_2 import org.moire.ultrasonic.data.MIGRATION_3_4 import org.moire.ultrasonic.data.MIGRATION_4_3 +import org.moire.ultrasonic.data.MIGRATION_4_5 +import org.moire.ultrasonic.data.MIGRATION_5_4 import org.moire.ultrasonic.model.ServerSettingsModel import org.moire.ultrasonic.util.Settings @@ -36,6 +38,8 @@ val appPermanentStorage = module { .addMigrations(MIGRATION_3_2) .addMigrations(MIGRATION_3_4) .addMigrations(MIGRATION_4_3) + .addMigrations(MIGRATION_4_5) + .addMigrations(MIGRATION_5_4) .build() } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ServerSelectorFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ServerSelectorFragment.kt index f5827d1f..d676e0ee 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ServerSelectorFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/ServerSelectorFragment.kt @@ -15,6 +15,7 @@ import kotlinx.coroutines.withContext import org.koin.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.viewModel import org.moire.ultrasonic.R +import org.moire.ultrasonic.adapters.ServerRowAdapter import org.moire.ultrasonic.data.ActiveServerProvider import org.moire.ultrasonic.fragment.EditServerFragment.Companion.EDIT_SERVER_INTENT_INDEX import org.moire.ultrasonic.model.ServerSettingsModel @@ -103,11 +104,10 @@ class ServerSelectorFragment : Fragment() { super.onResume() val serverList = serverSettingsModel.getServerList() serverList.observe( - this, - { t -> - serverRowAdapter!!.setData(t.toTypedArray()) - } - ) + this + ) { t -> + serverRowAdapter!!.setData(t.toTypedArray()) + } } /**