diff --git a/src/commonMain/kotlin/baaahs/api/ws/WebSocketClient.kt b/src/commonMain/kotlin/baaahs/api/ws/WebSocketClient.kt index e104fd773b..0f9f8e6856 100644 --- a/src/commonMain/kotlin/baaahs/api/ws/WebSocketClient.kt +++ b/src/commonMain/kotlin/baaahs/api/ws/WebSocketClient.kt @@ -80,7 +80,7 @@ class WebSocketClient( "loadSession", json.encodeToJsonElement(String.serializer(), name) ) - return mappingSessionStore.decode(response) + return mappingSessionStore.decode(response, name) } private suspend fun sendCommand(command: String, vararg args: JsonElement): JsonElement { diff --git a/src/commonMain/kotlin/baaahs/client/document/DataStore.kt b/src/commonMain/kotlin/baaahs/client/document/DataStore.kt index 2823b3257c..b7f682d476 100644 --- a/src/commonMain/kotlin/baaahs/client/document/DataStore.kt +++ b/src/commonMain/kotlin/baaahs/client/document/DataStore.kt @@ -16,20 +16,20 @@ class DataStore( private val plugins: Plugins, private val migrator: DataMigrator ) { - fun decode(content: String) = - plugins.json.decodeFromString(migrator, content) + fun decode(content: String, fileName: String? = null) = + plugins.json.decodeFromString(migrator.Migrate(fileName), content) - fun decode(content: JsonElement) = - plugins.json.decodeFromJsonElement(migrator, content) + fun decode(content: JsonElement, fileName: String? = null) = + plugins.json.decodeFromJsonElement(migrator.Migrate(fileName), content) suspend fun load(file: Fs.File): T? = - file.read()?.let { decode(it) } + file.read()?.let { decode(it, file.toString()) } fun encode(content: T) = - plugins.json.encodeToString(migrator, content) + plugins.json.encodeToString(migrator.Migrate(), content) fun encodeToJsonElement(content: T) = - plugins.json.encodeToJsonElement(migrator, content) + plugins.json.encodeToJsonElement(migrator.Migrate(), content) suspend fun save(file: Fs.File, content: T, allowOverwrite: Boolean = false) = file.write( diff --git a/src/commonMain/kotlin/baaahs/migrator/DataMigrator.kt b/src/commonMain/kotlin/baaahs/migrator/DataMigrator.kt index f5ecc5019b..8a82c12650 100644 --- a/src/commonMain/kotlin/baaahs/migrator/DataMigrator.kt +++ b/src/commonMain/kotlin/baaahs/migrator/DataMigrator.kt @@ -5,10 +5,10 @@ import kotlinx.serialization.KSerializer import kotlinx.serialization.json.* open class DataMigrator( - tSerializer: KSerializer, + private val tSerializer: KSerializer, private val migrations: List = emptyList(), private val versionKey: String = "version" -) : JsonTransformingSerializer(tSerializer) { +) { init { val versionDupes = migrations.groupBy { it.toVersion } .filter { (_, matching) -> matching.size > 1 } @@ -20,39 +20,45 @@ open class DataMigrator( } private val currentVersion = migrations.maxOfOrNull { it.toVersion } ?: 0 - override fun transformDeserialize(element: JsonElement): JsonElement { - if (element !is JsonObject) return element - val fromVersion = element[versionKey]?.jsonPrimitive?.int ?: 0 - if (fromVersion == currentVersion) - return element.toMutableMap() - .apply { remove(versionKey) }.toJsonObj() + inner class Migrate( + fileName: String? = null + ) : JsonTransformingSerializer(tSerializer) { + private val context = fileName?.let { "$it: " } ?: "" - var newJson = element - .toMutableMap().apply { - remove(versionKey) - }.toJsonObj() + override fun transformDeserialize(element: JsonElement): JsonElement { + if (element !is JsonObject) return element + val fromVersion = element[versionKey]?.jsonPrimitive?.int ?: 0 + if (fromVersion == currentVersion) + return element.toMutableMap() + .apply { remove(versionKey) }.toJsonObj() + + var newJson = element + .toMutableMap().apply { + remove(versionKey) + }.toJsonObj() - logger.debug { "Migrating from v$fromVersion:\n$newJson" } + logger.debug { "${context}Migrating from v$fromVersion:\n$newJson" } - migrations.forEach { migration -> - if (fromVersion < migration.toVersion) { - logger.info { - "Migrating from $fromVersion to ${migration.toVersion} (${migration::class.simpleName})." + migrations.forEach { migration -> + if (fromVersion < migration.toVersion) { + logger.info { + "${context}Migrating from $fromVersion to ${migration.toVersion} (${migration::class.simpleName})." + } + newJson = migration.migrate(newJson) } - newJson = migration.migrate(newJson) } - } - logger.debug { "Migrated to v$currentVersion:\n$newJson" } + logger.debug { "${context}Migrated to v$currentVersion:\n$newJson" } - return newJson.toJsonObj() - } + return newJson.toJsonObj() + } - override fun transformSerialize(element: JsonElement): JsonElement { - if (element !is JsonObject) return element - return element.toMutableMap().apply { - put(versionKey, JsonPrimitive(currentVersion)) - }.toJsonObj() + override fun transformSerialize(element: JsonElement): JsonElement { + if (element !is JsonObject) return element + return element.toMutableMap().apply { + put(versionKey, JsonPrimitive(currentVersion)) + }.toJsonObj() + } } abstract class Migration(val toVersion: Int) { diff --git a/src/commonMain/kotlin/baaahs/show/migration/V10_RemoveVarPrefixFromXyPad.kt b/src/commonMain/kotlin/baaahs/show/migration/V10_RemoveVarPrefixFromXyPad.kt index 29913375e4..d29f1b225e 100644 --- a/src/commonMain/kotlin/baaahs/show/migration/V10_RemoveVarPrefixFromXyPad.kt +++ b/src/commonMain/kotlin/baaahs/show/migration/V10_RemoveVarPrefixFromXyPad.kt @@ -14,7 +14,6 @@ object V10_RemoveVarPrefixFromXyPad : DataMigrator.Migration(10) { override fun migrate(from: JsonObject): JsonObject { return from.toMutableMap().apply { mapObjsInDict("feeds") { _, control -> - println("from = $control") if (control.type == "baaahs.Core:XyPad") { control.remove("varPrefix") } diff --git a/src/jsMain/kotlin/baaahs/app/ui/UiActions.kt b/src/jsMain/kotlin/baaahs/app/ui/UiActions.kt index bac98ae286..f77aa24d8c 100644 --- a/src/jsMain/kotlin/baaahs/app/ui/UiActions.kt +++ b/src/jsMain/kotlin/baaahs/app/ui/UiActions.kt @@ -20,14 +20,14 @@ actual object UiActions { val type = FileType.Show val filename = "${show.title}${type.extension}" val contentType = "application/json;charset=utf-8;" - doDownload(filename, show, ShowMigrator, contentType, plugins) + doDownload(filename, show, ShowMigrator.Migrate(filename), contentType, plugins) } actual fun downloadScene(scene: Scene, plugins: Plugins) { val type = FileType.Scene val filename = "${scene.title}${type.extension}" val contentType = "application/json;charset=utf-8;" - doDownload(filename, scene, SceneMigrator, contentType, plugins) + doDownload(filename, scene, SceneMigrator.Migrate(filename), contentType, plugins) } private fun doDownload(