mirror of
https://github.com/Suwayomi/Suwayomi-Server.git
synced 2026-06-30 17:34:39 -05:00
move migration lib outside of Tachidesk
This commit is contained in:
@@ -44,11 +44,16 @@ dependencies {
|
|||||||
// current database driver
|
// current database driver
|
||||||
implementation("com.h2database:h2:1.4.200")
|
implementation("com.h2database:h2:1.4.200")
|
||||||
|
|
||||||
|
// Exposed Migrations
|
||||||
|
val exposedMigrationsVersion = "5611dbec5a"
|
||||||
|
implementation("com.github.Suwayomi:exposed-migrations:$exposedMigrationsVersion")
|
||||||
|
|
||||||
// tray icon
|
// tray icon
|
||||||
implementation("com.dorkbox:SystemTray:4.1")
|
implementation("com.dorkbox:SystemTray:4.1")
|
||||||
implementation("com.dorkbox:Utilities:1.9")
|
implementation("com.dorkbox:Utilities:1.9")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// dependencies of Tachiyomi extensions, some are duplicate, keeping it here for reference
|
// dependencies of Tachiyomi extensions, some are duplicate, keeping it here for reference
|
||||||
implementation("com.github.inorichi.injekt:injekt-core:65b0440")
|
implementation("com.github.inorichi.injekt:injekt-core:65b0440")
|
||||||
implementation("com.squareup.okhttp3:okhttp:4.9.1")
|
implementation("com.squareup.okhttp3:okhttp:4.9.1")
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import org.kodein.di.DI
|
|||||||
import org.kodein.di.bind
|
import org.kodein.di.bind
|
||||||
import org.kodein.di.conf.global
|
import org.kodein.di.conf.global
|
||||||
import org.kodein.di.singleton
|
import org.kodein.di.singleton
|
||||||
import suwayomi.tachidesk.server.BuildConfig
|
|
||||||
import suwayomi.tachidesk.server.database.databaseUp
|
import suwayomi.tachidesk.server.database.databaseUp
|
||||||
import suwayomi.tachidesk.server.util.AppMutex.handleAppMutex
|
import suwayomi.tachidesk.server.util.AppMutex.handleAppMutex
|
||||||
import suwayomi.tachidesk.server.util.SystemTray.systemTray
|
import suwayomi.tachidesk.server.util.SystemTray.systemTray
|
||||||
|
|||||||
@@ -7,13 +7,14 @@ package suwayomi.tachidesk.server.database
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import de.neonew.exposed.migrations.loadMigrationsFrom
|
||||||
|
import de.neonew.exposed.migrations.runMigrations
|
||||||
import org.jetbrains.exposed.sql.Database
|
import org.jetbrains.exposed.sql.Database
|
||||||
import org.kodein.di.DI
|
import org.kodein.di.DI
|
||||||
import org.kodein.di.conf.global
|
import org.kodein.di.conf.global
|
||||||
import org.kodein.di.instance
|
import org.kodein.di.instance
|
||||||
import suwayomi.tachidesk.server.ApplicationDirs
|
import suwayomi.tachidesk.server.ApplicationDirs
|
||||||
import suwayomi.tachidesk.server.database.migration.lib.loadMigrationsFrom
|
import suwayomi.tachidesk.server.ServerConfig
|
||||||
import suwayomi.tachidesk.server.database.migration.lib.runMigrations
|
|
||||||
|
|
||||||
object DBManager {
|
object DBManager {
|
||||||
val db by lazy {
|
val db by lazy {
|
||||||
@@ -27,6 +28,6 @@ fun databaseUp() {
|
|||||||
val db = DBManager.db
|
val db = DBManager.db
|
||||||
db.useNestedTransactions = true
|
db.useNestedTransactions = true
|
||||||
|
|
||||||
val migrations = loadMigrationsFrom("suwayomi.tachidesk.server.database.migration")
|
val migrations = loadMigrationsFrom("suwayomi.tachidesk.server.database.migration", ServerConfig::class.java)
|
||||||
runMigrations(migrations)
|
runMigrations(migrations)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ package suwayomi.tachidesk.server.database.migration
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import de.neonew.exposed.migrations.Migration
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import org.jetbrains.exposed.dao.id.IdTable
|
import org.jetbrains.exposed.dao.id.IdTable
|
||||||
import org.jetbrains.exposed.dao.id.IntIdTable
|
import org.jetbrains.exposed.dao.id.IntIdTable
|
||||||
import org.jetbrains.exposed.sql.SchemaUtils
|
import org.jetbrains.exposed.sql.SchemaUtils
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import suwayomi.tachidesk.server.database.migration.lib.Migration
|
|
||||||
|
|
||||||
@Suppress("ClassName", "unused")
|
@Suppress("ClassName", "unused")
|
||||||
class M0001_Initial : Migration() {
|
class M0001_Initial : Migration() {
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ package suwayomi.tachidesk.server.database.migration
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import de.neonew.exposed.migrations.Migration
|
||||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||||
import org.jetbrains.exposed.sql.vendors.currentDialect
|
import org.jetbrains.exposed.sql.vendors.currentDialect
|
||||||
import suwayomi.tachidesk.server.database.migration.lib.Migration
|
|
||||||
|
|
||||||
@Suppress("ClassName", "unused")
|
@Suppress("ClassName", "unused")
|
||||||
class M0002_ChapterTableIndexRename : Migration() {
|
class M0002_ChapterTableIndexRename : Migration() {
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ package suwayomi.tachidesk.server.database.migration
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import de.neonew.exposed.migrations.Migration
|
||||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||||
import org.jetbrains.exposed.sql.vendors.currentDialect
|
import org.jetbrains.exposed.sql.vendors.currentDialect
|
||||||
import suwayomi.tachidesk.server.database.migration.lib.Migration
|
|
||||||
|
|
||||||
@Suppress("ClassName", "unused")
|
@Suppress("ClassName", "unused")
|
||||||
class M0003_DefaultCategory : Migration() {
|
class M0003_DefaultCategory : Migration() {
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
package suwayomi.tachidesk.server.database.migration
|
package suwayomi.tachidesk.server.database.migration
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import de.neonew.exposed.migrations.Migration
|
||||||
import org.jetbrains.exposed.dao.id.IdTable
|
import org.jetbrains.exposed.dao.id.IdTable
|
||||||
import org.jetbrains.exposed.dao.id.IntIdTable
|
import org.jetbrains.exposed.dao.id.IntIdTable
|
||||||
import org.jetbrains.exposed.sql.SchemaUtils
|
import org.jetbrains.exposed.sql.SchemaUtils
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import suwayomi.tachidesk.server.database.migration.lib.Migration
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
class M0004_AnimeTablesBatch1 : Migration() {
|
class M0004_AnimeTablesBatch1 : Migration() {
|
||||||
private class AnimeExtensionTable : IntIdTable() {
|
private class AnimeExtensionTable : IntIdTable() {
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
package suwayomi.tachidesk.server.database.migration
|
package suwayomi.tachidesk.server.database.migration
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import de.neonew.exposed.migrations.Migration
|
||||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||||
import org.jetbrains.exposed.dao.id.IntIdTable
|
import org.jetbrains.exposed.dao.id.IntIdTable
|
||||||
import org.jetbrains.exposed.sql.SchemaUtils
|
import org.jetbrains.exposed.sql.SchemaUtils
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import suwayomi.tachidesk.server.database.migration.lib.Migration
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
class M0005_AnimeTablesBatch2 : Migration() {
|
class M0005_AnimeTablesBatch2 : Migration() {
|
||||||
private class AnimeTable : IntIdTable() {
|
private class AnimeTable : IntIdTable() {
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
package suwayomi.tachidesk.server.database.migration
|
package suwayomi.tachidesk.server.database.migration
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import de.neonew.exposed.migrations.Migration
|
||||||
import org.jetbrains.exposed.dao.id.IntIdTable
|
import org.jetbrains.exposed.dao.id.IntIdTable
|
||||||
import org.jetbrains.exposed.sql.SchemaUtils
|
import org.jetbrains.exposed.sql.SchemaUtils
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import suwayomi.tachidesk.anime.model.table.AnimeTable
|
import suwayomi.tachidesk.anime.model.table.AnimeTable
|
||||||
import suwayomi.tachidesk.server.database.migration.lib.Migration
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
class M0006_AnimeTablesBatch3 : Migration() {
|
class M0006_AnimeTablesBatch3 : Migration() {
|
||||||
private class EpisodeTable : IntIdTable() {
|
private class EpisodeTable : IntIdTable() {
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ package suwayomi.tachidesk.server.database.migration
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import de.neonew.exposed.migrations.Migration
|
||||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||||
import org.jetbrains.exposed.sql.vendors.currentDialect
|
import org.jetbrains.exposed.sql.vendors.currentDialect
|
||||||
import suwayomi.tachidesk.server.database.migration.lib.Migration
|
|
||||||
|
|
||||||
@Suppress("ClassName", "unused")
|
@Suppress("ClassName", "unused")
|
||||||
class M0007_ChapterIsDownloaded : Migration() {
|
class M0007_ChapterIsDownloaded : Migration() {
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ package suwayomi.tachidesk.server.database.migration
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import de.neonew.exposed.migrations.Migration
|
||||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||||
import org.jetbrains.exposed.sql.vendors.currentDialect
|
import org.jetbrains.exposed.sql.vendors.currentDialect
|
||||||
import suwayomi.tachidesk.server.database.migration.lib.Migration
|
|
||||||
|
|
||||||
@Suppress("ClassName", "unused")
|
@Suppress("ClassName", "unused")
|
||||||
class M0008_ChapterPageCount : Migration() {
|
class M0008_ChapterPageCount : Migration() {
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ package suwayomi.tachidesk.server.database.migration
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import de.neonew.exposed.migrations.Migration
|
||||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||||
import org.jetbrains.exposed.sql.vendors.currentDialect
|
import org.jetbrains.exposed.sql.vendors.currentDialect
|
||||||
import suwayomi.tachidesk.server.database.migration.lib.Migration
|
|
||||||
|
|
||||||
@Suppress("ClassName", "unused")
|
@Suppress("ClassName", "unused")
|
||||||
class M0009_ChapterLastReadAt : Migration() {
|
class M0009_ChapterLastReadAt : Migration() {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package suwayomi.tachidesk.server.database.migration
|
package suwayomi.tachidesk.server.database.migration
|
||||||
|
|
||||||
|
import de.neonew.exposed.migrations.Migration
|
||||||
import org.jetbrains.exposed.dao.id.IntIdTable
|
import org.jetbrains.exposed.dao.id.IntIdTable
|
||||||
import org.jetbrains.exposed.sql.ReferenceOption
|
import org.jetbrains.exposed.sql.ReferenceOption
|
||||||
import org.jetbrains.exposed.sql.SchemaUtils
|
import org.jetbrains.exposed.sql.SchemaUtils
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import suwayomi.tachidesk.manga.model.table.ChapterTable
|
import suwayomi.tachidesk.manga.model.table.ChapterTable
|
||||||
import suwayomi.tachidesk.manga.model.table.MangaTable
|
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||||
import suwayomi.tachidesk.server.database.migration.lib.Migration
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2020 Andreas Mausch
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
package suwayomi.tachidesk.server.database.migration.lib
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
// originally licenced under MIT by Andreas Mausch, Changes are licenced under Mozilla Public License, v. 2.0.
|
|
||||||
// adopted from: https://gitlab.com/andreas-mausch/exposed-migrations/-/tree/4bf853c18a24d0170eda896ddbb899cb01233595
|
|
||||||
|
|
||||||
abstract class Migration {
|
|
||||||
val name: String
|
|
||||||
val version: Int
|
|
||||||
|
|
||||||
init {
|
|
||||||
val groups = Regex("^M(\\d+)_(.*)$").matchEntire(this::class.simpleName!!)?.groupValues
|
|
||||||
?: throw IllegalArgumentException("Migration class name doesn't match convention")
|
|
||||||
version = groups[1].toInt()
|
|
||||||
name = groups[2]
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract fun run()
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package suwayomi.tachidesk.server.database.migration.lib
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
// originally licenced under MIT by Andreas Mausch, Changes are licenced under Mozilla Public License, v. 2.0.
|
|
||||||
// adopted from: https://gitlab.com/andreas-mausch/exposed-migrations/-/tree/4bf853c18a24d0170eda896ddbb899cb01233595
|
|
||||||
|
|
||||||
import org.jetbrains.exposed.dao.IntEntity
|
|
||||||
import org.jetbrains.exposed.dao.IntEntityClass
|
|
||||||
import org.jetbrains.exposed.dao.id.EntityID
|
|
||||||
import org.jetbrains.exposed.dao.id.IdTable
|
|
||||||
import org.jetbrains.exposed.sql.`java-time`.timestamp
|
|
||||||
|
|
||||||
object MigrationsTable : IdTable<Int>() {
|
|
||||||
override val id = integer("version").entityId()
|
|
||||||
override val primaryKey = PrimaryKey(id)
|
|
||||||
|
|
||||||
val name = varchar("name", length = 400)
|
|
||||||
val executedAt = timestamp("executed_at")
|
|
||||||
|
|
||||||
init {
|
|
||||||
index(true, name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MigrationEntity(id: EntityID<Int>) : IntEntity(id) {
|
|
||||||
companion object : IntEntityClass<MigrationEntity>(MigrationsTable)
|
|
||||||
|
|
||||||
var version by MigrationsTable.id
|
|
||||||
var name by MigrationsTable.name
|
|
||||||
var executedAt by MigrationsTable.executedAt
|
|
||||||
}
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
package suwayomi.tachidesk.server.database.migration.lib
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
// originally licenced under MIT by Andreas Mausch, Changes are licenced under Mozilla Public License, v. 2.0.
|
|
||||||
// adopted from: https://gitlab.com/andreas-mausch/exposed-migrations/-/tree/4bf853c18a24d0170eda896ddbb899cb01233595
|
|
||||||
|
|
||||||
import mu.KotlinLogging
|
|
||||||
import org.jetbrains.exposed.dao.id.EntityID
|
|
||||||
import org.jetbrains.exposed.sql.Database
|
|
||||||
import org.jetbrains.exposed.sql.SchemaUtils.create
|
|
||||||
import org.jetbrains.exposed.sql.exists
|
|
||||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
|
||||||
import suwayomi.tachidesk.server.ServerConfig
|
|
||||||
import java.nio.file.FileSystems
|
|
||||||
import java.nio.file.Files
|
|
||||||
import java.nio.file.Paths
|
|
||||||
import java.time.Clock
|
|
||||||
import java.time.Instant.now
|
|
||||||
import kotlin.io.path.ExperimentalPathApi
|
|
||||||
import kotlin.io.path.isDirectory
|
|
||||||
import kotlin.io.path.name
|
|
||||||
import kotlin.streams.toList
|
|
||||||
|
|
||||||
private val logger = KotlinLogging.logger {}
|
|
||||||
|
|
||||||
fun runMigrations(migrations: List<Migration>, database: Database = TransactionManager.defaultDatabase!!, clock: Clock = Clock.systemUTC()) {
|
|
||||||
checkVersions(migrations)
|
|
||||||
|
|
||||||
logger.info { "Running migrations on database ${database.url}" }
|
|
||||||
|
|
||||||
val latestVersion = transaction(database) {
|
|
||||||
createTableIfNotExists(database)
|
|
||||||
MigrationEntity.all().maxByOrNull { it.version }?.version?.value
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info { "Database version before migrations: $latestVersion" }
|
|
||||||
|
|
||||||
migrations
|
|
||||||
.sortedBy { it.version }
|
|
||||||
.filter { shouldRun(latestVersion, it) }
|
|
||||||
.forEach {
|
|
||||||
logger.info { "Running migration version ${it.version}: ${it.name}" }
|
|
||||||
transaction(database) {
|
|
||||||
it.run()
|
|
||||||
|
|
||||||
MigrationEntity.new {
|
|
||||||
version = EntityID(it.version, MigrationsTable)
|
|
||||||
name = it.name
|
|
||||||
executedAt = now(clock)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info { "Migrations finished successfully" }
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalPathApi::class)
|
|
||||||
private fun getTopLevelClasses(packageName: String): List<Class<*>> {
|
|
||||||
ServerConfig::class.java.getResource("/" + packageName.replace('.', '/'))
|
|
||||||
val path = "/" + packageName.replace('.', '/')
|
|
||||||
val uri = ServerConfig::class.java.getResource(path).toURI()
|
|
||||||
|
|
||||||
return when (uri.scheme) {
|
|
||||||
"jar" -> {
|
|
||||||
val fileSystem = FileSystems.newFileSystem(uri, emptyMap<String, Any>())
|
|
||||||
fileSystem.getPath(path)
|
|
||||||
}
|
|
||||||
else -> Paths.get(uri)
|
|
||||||
}.let { Files.walk(it, 1) }
|
|
||||||
.toList()
|
|
||||||
.filterNot { it.isDirectory() || it.name.contains('$') } // '$' means it's not a top level class
|
|
||||||
.filter { it.name.endsWith(".class") }
|
|
||||||
.map { Class.forName("$packageName.${it.name.substringBefore(".class")}") }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("UnstableApiUsage")
|
|
||||||
fun loadMigrationsFrom(packageName: String): List<Migration> {
|
|
||||||
return getTopLevelClasses(packageName)
|
|
||||||
.map {
|
|
||||||
logger.debug("found Migration class ${it.name}")
|
|
||||||
val clazz = it.getDeclaredConstructor().newInstance()
|
|
||||||
if (clazz is Migration)
|
|
||||||
clazz
|
|
||||||
else
|
|
||||||
throw RuntimeException("found a class that's not a Migration")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkVersions(migrations: List<Migration>) {
|
|
||||||
val sorted = migrations.map { it.version }.sorted()
|
|
||||||
if ((1..migrations.size).toList() != sorted) {
|
|
||||||
throw IllegalStateException("List of migrations version is not consecutive: $sorted")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createTableIfNotExists(database: Database) {
|
|
||||||
if (MigrationsTable.exists()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val tableNames = database.dialect.allTablesNames()
|
|
||||||
when (tableNames.isEmpty()) {
|
|
||||||
true -> {
|
|
||||||
logger.info { "Empty database found, creating table for migrations" }
|
|
||||||
create(MigrationsTable)
|
|
||||||
}
|
|
||||||
false -> throw IllegalStateException("Tried to run migrations against a non-empty database without a Migrations table. This is not supported.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun shouldRun(latestVersion: Int?, migration: Migration): Boolean {
|
|
||||||
val run = latestVersion?.let { migration.version > it } ?: true
|
|
||||||
if (!run) {
|
|
||||||
logger.debug { "Skipping migration version ${migration.version}: ${migration.name}" }
|
|
||||||
}
|
|
||||||
return run
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user