Fix database migration for existing installs

This commit is contained in:
Niels van Velzen
2026-06-14 17:30:54 +02:00
committed by Niels van Velzen
parent fb7ebed903
commit b5ee1feb0f
3 changed files with 86 additions and 321 deletions
@@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 5,
"identityHash": "bb9e921c1ce696cf9a83c92fff1903e1",
"identityHash": "311b7804b1eb8748f7ddaaf8f483ed22",
"entities": [
{
"tableName": "server",
@@ -229,11 +229,89 @@
]
}
]
},
{
"tableName": "download_file",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `download_id` INTEGER NOT NULL, `type` TEXT NOT NULL, `size` INTEGER NOT NULL, `file_name` TEXT NOT NULL, `uri` TEXT NOT NULL, `status` TEXT NOT NULL, FOREIGN KEY(`download_id`) REFERENCES `download`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "downloadId",
"columnName": "download_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "size",
"columnName": "size",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "fileName",
"columnName": "file_name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "uri",
"columnName": "uri",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "status",
"columnName": "status",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_download_file_download_id",
"unique": false,
"columnNames": [
"download_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_download_file_download_id` ON `${TABLE_NAME}` (`download_id`)"
}
],
"foreignKeys": [
{
"table": "download",
"onDelete": "CASCADE",
"onUpdate": "NO ACTION",
"columns": [
"download_id"
],
"referencedColumns": [
"id"
]
}
]
}
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'bb9e921c1ce696cf9a83c92fff1903e1')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '311b7804b1eb8748f7ddaaf8f483ed22')"
]
}
}
@@ -1,317 +0,0 @@
{
"formatVersion": 1,
"database": {
"version": 6,
"identityHash": "311b7804b1eb8748f7ddaaf8f483ed22",
"entities": [
{
"tableName": "server",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `hostname` TEXT NOT NULL, `last_used_timestamp` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "hostname",
"columnName": "hostname",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "lastUsedTimestamp",
"columnName": "last_used_timestamp",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_server_hostname",
"unique": true,
"columnNames": [
"hostname"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_server_hostname` ON `${TABLE_NAME}` (`hostname`)"
}
]
},
{
"tableName": "user",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `server_id` INTEGER NOT NULL, `user_id` TEXT NOT NULL, `access_token` TEXT, `last_login_timestamp` INTEGER NOT NULL, FOREIGN KEY(`server_id`) REFERENCES `server`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "serverId",
"columnName": "server_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "accessToken",
"columnName": "access_token",
"affinity": "TEXT"
},
{
"fieldPath": "lastLoginTimestamp",
"columnName": "last_login_timestamp",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_user_server_id_user_id",
"unique": true,
"columnNames": [
"server_id",
"user_id"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_user_server_id_user_id` ON `${TABLE_NAME}` (`server_id`, `user_id`)"
}
],
"foreignKeys": [
{
"table": "server",
"onDelete": "NO ACTION",
"onUpdate": "NO ACTION",
"columns": [
"server_id"
],
"referencedColumns": [
"id"
]
}
]
},
{
"tableName": "download",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `server_id` INTEGER NOT NULL, `user_id` INTEGER NOT NULL, `item_id` TEXT NOT NULL, `path` TEXT NOT NULL, `item` TEXT NOT NULL, `status` TEXT NOT NULL, `created_at` INTEGER NOT NULL, `modified_at` INTEGER NOT NULL, FOREIGN KEY(`server_id`) REFERENCES `server`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`user_id`) REFERENCES `user`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "serverId",
"columnName": "server_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "userId",
"columnName": "user_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "itemId",
"columnName": "item_id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "path",
"columnName": "path",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "item",
"columnName": "item",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "status",
"columnName": "status",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "createdAt",
"columnName": "created_at",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "modifiedAt",
"columnName": "modified_at",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_download_server_id",
"unique": false,
"columnNames": [
"server_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_download_server_id` ON `${TABLE_NAME}` (`server_id`)"
},
{
"name": "index_download_user_id",
"unique": false,
"columnNames": [
"user_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_download_user_id` ON `${TABLE_NAME}` (`user_id`)"
},
{
"name": "index_download_item_id",
"unique": false,
"columnNames": [
"item_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_download_item_id` ON `${TABLE_NAME}` (`item_id`)"
}
],
"foreignKeys": [
{
"table": "server",
"onDelete": "CASCADE",
"onUpdate": "NO ACTION",
"columns": [
"server_id"
],
"referencedColumns": [
"id"
]
},
{
"table": "user",
"onDelete": "CASCADE",
"onUpdate": "NO ACTION",
"columns": [
"user_id"
],
"referencedColumns": [
"id"
]
}
]
},
{
"tableName": "download_file",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `download_id` INTEGER NOT NULL, `type` TEXT NOT NULL, `size` INTEGER NOT NULL, `file_name` TEXT NOT NULL, `uri` TEXT NOT NULL, `status` TEXT NOT NULL, FOREIGN KEY(`download_id`) REFERENCES `download`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "downloadId",
"columnName": "download_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "size",
"columnName": "size",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "fileName",
"columnName": "file_name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "uri",
"columnName": "uri",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "status",
"columnName": "status",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_download_file_download_id",
"unique": false,
"columnNames": [
"download_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_download_file_download_id` ON `${TABLE_NAME}` (`download_id`)"
}
],
"foreignKeys": [
{
"table": "download",
"onDelete": "CASCADE",
"onUpdate": "NO ACTION",
"columns": [
"download_id"
],
"referencedColumns": [
"id"
]
}
]
}
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '311b7804b1eb8748f7ddaaf8f483ed22')"
]
}
}
@@ -3,6 +3,7 @@ package org.jellyfin.mobile.data
import android.net.Uri
import androidx.room.AutoMigration
import androidx.room.Database
import androidx.room.DeleteTable
import androidx.room.RenameTable
import androidx.room.RoomDatabase
import androidx.room.TypeConverter
@@ -29,11 +30,11 @@ import java.util.UUID
DownloadEntity::class,
DownloadFileEntity::class,
],
version = 6,
version = 5,
autoMigrations = [
AutoMigration(from = 2, to = 3),
AutoMigration(from = 3, to = 4, spec = JellyfinDatabase.MigrateV4::class),
AutoMigration(from = 5, to = 6),
AutoMigration(from = 4, to = 5, spec = JellyfinDatabase.MigrateV5::class),
],
)
@TypeConverters(JellyfinDatabase.Converters::class)
@@ -87,4 +88,7 @@ abstract class JellyfinDatabase : RoomDatabase() {
cursor.close()
}
}
@DeleteTable(tableName = "Download")
class MigrateV5 : AutoMigrationSpec
}