mirror of
https://github.com/Suwayomi/Suwayomi-Server.git
synced 2026-06-30 09:24:34 -05:00
Update H2
This commit is contained in:
@@ -70,11 +70,11 @@ exposed-jdbc = { module = "org.jetbrains.exposed:exposed-jdbc", version.ref = "e
|
||||
exposed-javatime = { module = "org.jetbrains.exposed:exposed-java-time", version.ref = "exposed" }
|
||||
exposed-kotlintime = { module = "org.jetbrains.exposed:exposed-kotlin-datetime", version.ref = "exposed" }
|
||||
postgres = "org.postgresql:postgresql:42.7.11"
|
||||
h2 = "com.h2database:h2:1.4.200" # current database driver, can't update to h2 v2 without sql migration
|
||||
h2 = "com.h2database:h2:2.4.240"
|
||||
hikaricp = "com.zaxxer:HikariCP:7.0.2"
|
||||
|
||||
# Exposed Migrations
|
||||
exposed-migrations = "com.github.Suwayomi:exposed-migrations:3.10.0"
|
||||
exposed-migrations = "com.github.Suwayomi:exposed-migrations:3.10.1"
|
||||
|
||||
# Dependency Injection
|
||||
koin-core = { module = "io.insert-koin:koin-core", version.ref = "koin" }
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.app.Application
|
||||
import android.content.Context
|
||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||
import suwayomi.tachidesk.manga.impl.update.IUpdater
|
||||
import suwayomi.tachidesk.server.database.H2Migration
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.File
|
||||
@@ -74,6 +75,14 @@ private fun migrateMangaDownloadDir(applicationDirs: ApplicationDirs) {
|
||||
}
|
||||
}
|
||||
|
||||
fun migrateDatabaseToV24240(applicationDirs: ApplicationDirs) {
|
||||
H2Migration.migrate(
|
||||
applicationDirs.dataRoot,
|
||||
"1.4.200",
|
||||
"2.4.240",
|
||||
)
|
||||
}
|
||||
|
||||
private val MIGRATIONS =
|
||||
listOf<Pair<String, (ApplicationDirs) -> Unit>>(
|
||||
"InitialMigration" to { applicationDirs ->
|
||||
@@ -83,6 +92,9 @@ private val MIGRATIONS =
|
||||
"FixGlobalUpdateScheduling" to {
|
||||
Injekt.get<IUpdater>().deleteLastAutomatedUpdateTimestamp()
|
||||
},
|
||||
"MigrateDatabaseToV2.4.240" to { applicationDirs ->
|
||||
migrateDatabaseToV24240(applicationDirs)
|
||||
},
|
||||
)
|
||||
|
||||
fun runMigrations(applicationDirs: ApplicationDirs) {
|
||||
|
||||
@@ -391,6 +391,8 @@ fun applicationSetup() {
|
||||
"Localization service initialized. Supported languages: ${LocalizationHelper.getSupportedLocales()}"
|
||||
}
|
||||
|
||||
runMigrations(applicationDirs)
|
||||
|
||||
databaseUp()
|
||||
|
||||
LocalSource.register()
|
||||
@@ -440,8 +442,6 @@ fun applicationSetup() {
|
||||
ignoreInitialValue = false,
|
||||
)
|
||||
|
||||
runMigrations(applicationDirs)
|
||||
|
||||
setLogLevelFor("org.eclipse.jetty", Level.OFF)
|
||||
setLogLevelFor("com.zaxxer.hikari", Level.WARN)
|
||||
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
package suwayomi.tachidesk.server.database
|
||||
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.net.URLClassLoader
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.Path
|
||||
import kotlin.io.path.absolutePathString
|
||||
import kotlin.io.path.copyTo
|
||||
import kotlin.io.path.createDirectories
|
||||
import kotlin.io.path.deleteExisting
|
||||
import kotlin.io.path.div
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.name
|
||||
import kotlin.io.path.notExists
|
||||
import kotlin.io.path.outputStream
|
||||
|
||||
object H2Migration {
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
private val client by lazy {
|
||||
Injekt.get<NetworkHelper>().client
|
||||
}
|
||||
|
||||
private const val TOOL_VERSION = "1.8"
|
||||
|
||||
private const val TOOL_URL =
|
||||
"https://manticore-projects.com/download/H2MigrationTool-$TOOL_VERSION/H2MigrationTool-$TOOL_VERSION-all.jar"
|
||||
|
||||
private const val MAVEN_BASE =
|
||||
"https://repo1.maven.org/maven2/com/h2database/h2"
|
||||
|
||||
fun migrate(
|
||||
rootDir: String,
|
||||
h2Old: String,
|
||||
h2New: String,
|
||||
) {
|
||||
val dbBase = "$rootDir/database"
|
||||
val mvStore = Path("$dbBase.mv.db")
|
||||
if (mvStore.notExists()) {
|
||||
logger.info { "No H2 database found. Skipping migration." }
|
||||
return
|
||||
}
|
||||
|
||||
val script = Path("$dbBase.${h2Old.substringAfterLast('.')}.sql")
|
||||
|
||||
// Backup original database.
|
||||
val backup = Path("$dbBase.mv.db.${h2Old.substringAfterLast('.')}.backup")
|
||||
mvStore.copyTo(backup, overwrite = true)
|
||||
logger.info { "Created backup: ${backup.absolutePathString()}" }
|
||||
|
||||
val toolsDir = Path(rootDir) / "bin" / "h2-migration-tools"
|
||||
val libsDir = toolsDir / "h2libs"
|
||||
libsDir.createDirectories()
|
||||
|
||||
// Download migration tool
|
||||
val migrationJar =
|
||||
toolsDir.resolve("H2MigrationTool-$TOOL_VERSION-all.jar")
|
||||
downloadIfNeeded(
|
||||
TOOL_URL,
|
||||
migrationJar,
|
||||
)
|
||||
downloadIfNeeded(
|
||||
"$MAVEN_BASE/$h2Old/h2-$h2Old.jar",
|
||||
libsDir.resolve("h2-$h2Old.bin"),
|
||||
)
|
||||
downloadIfNeeded(
|
||||
"$MAVEN_BASE/$h2New/h2-$h2New.jar",
|
||||
libsDir.resolve("h2-$h2New.bin"),
|
||||
)
|
||||
|
||||
runMigrationTool(
|
||||
migrationJar = migrationJar,
|
||||
libsDir = libsDir,
|
||||
mvStore = mvStore,
|
||||
script = script,
|
||||
)
|
||||
|
||||
// Move database to proper path
|
||||
val newDatabase = Path(rootDir, "database.${h2New.substringAfterLast('.')}.mv.db")
|
||||
newDatabase.copyTo(mvStore, overwrite = true)
|
||||
newDatabase.deleteExisting()
|
||||
|
||||
logger.info { "H2 migration completed successfully." }
|
||||
}
|
||||
|
||||
private fun downloadIfNeeded(
|
||||
url: String,
|
||||
output: Path,
|
||||
) {
|
||||
if (output.exists()) {
|
||||
logger.debug { "Already downloaded: ${output.name}" }
|
||||
return
|
||||
}
|
||||
|
||||
client
|
||||
.newCall(GET(url))
|
||||
.execute()
|
||||
.use { response ->
|
||||
|
||||
if (!response.isSuccessful) {
|
||||
throw RuntimeException(
|
||||
"Failed to download $url " +
|
||||
"(HTTP ${response.code})",
|
||||
)
|
||||
}
|
||||
|
||||
output.outputStream().use { out ->
|
||||
response.body.byteStream().copyTo(out)
|
||||
}
|
||||
}
|
||||
|
||||
logger.info { "Saved: ${output.absolutePathString()}" }
|
||||
}
|
||||
|
||||
private fun runMigrationTool(
|
||||
migrationJar: Path,
|
||||
libsDir: Path,
|
||||
mvStore: Path,
|
||||
script: Path,
|
||||
) {
|
||||
URLClassLoader(
|
||||
arrayOf(migrationJar.toUri().toURL()),
|
||||
javaClass.classLoader,
|
||||
).use { classLoader ->
|
||||
val clazz =
|
||||
classLoader.loadClass("com.manticore.h2.H2MigrationTool")
|
||||
|
||||
val main =
|
||||
clazz.getMethod("main", Array<String>::class.java)
|
||||
|
||||
main.invoke(
|
||||
null,
|
||||
arrayOf(
|
||||
// h2 driver dir
|
||||
"-l",
|
||||
libsDir.absolutePathString(),
|
||||
// from version
|
||||
"-f",
|
||||
"1.4.200",
|
||||
// to version
|
||||
"-t",
|
||||
"2.4.240",
|
||||
// user
|
||||
"-u",
|
||||
"",
|
||||
// password
|
||||
"-p",
|
||||
"",
|
||||
// database.mv.db
|
||||
"-d",
|
||||
mvStore.absolutePathString(),
|
||||
// database backup in SQL
|
||||
"-s",
|
||||
script.absolutePathString(),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user