Make it clear which ID the OfflineServer has (-1)

Also provide migration path to future version
This commit is contained in:
tzugen 2022-03-27 13:43:03 +02:00
parent 1d88c585c4
commit 1a46f7e2c6
No known key found for this signature in database
GPG Key ID: 61E9C34BC10EC930
6 changed files with 133 additions and 41 deletions

View File

@ -1,4 +1,4 @@
package org.moire.ultrasonic.fragment
package org.moire.ultrasonic.adapters
import android.content.Context
import android.graphics.drawable.Drawable

View File

@ -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<Int> = 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
}
/**

View File

@ -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`")
}
}

View File

@ -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
)
}

View File

@ -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()
}

View File

@ -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())
}
}
/**