mirror of
https://github.com/Suwayomi/Suwayomi-Server.git
synced 2026-07-05 03:44:36 -05:00
move databse to server package, move tables to a better place
This commit is contained in:
@@ -15,9 +15,9 @@ import org.jetbrains.exposed.sql.selectAll
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import org.jetbrains.exposed.sql.update
|
||||
import suwayomi.tachidesk.impl.CategoryManga.removeMangaFromCategory
|
||||
import suwayomi.tachidesk.model.database.table.CategoryMangaTable
|
||||
import suwayomi.tachidesk.model.database.table.CategoryTable
|
||||
import suwayomi.tachidesk.model.database.table.toDataClass
|
||||
import suwayomi.tachidesk.model.table.CategoryMangaTable
|
||||
import suwayomi.tachidesk.model.table.CategoryTable
|
||||
import suwayomi.tachidesk.model.table.toDataClass
|
||||
import suwayomi.tachidesk.model.dataclass.CategoryDataClass
|
||||
|
||||
object Category {
|
||||
|
||||
@@ -14,10 +14,10 @@ import org.jetbrains.exposed.sql.insert
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import org.jetbrains.exposed.sql.update
|
||||
import suwayomi.tachidesk.model.database.table.CategoryMangaTable
|
||||
import suwayomi.tachidesk.model.database.table.CategoryTable
|
||||
import suwayomi.tachidesk.model.database.table.MangaTable
|
||||
import suwayomi.tachidesk.model.database.table.toDataClass
|
||||
import suwayomi.tachidesk.model.table.CategoryMangaTable
|
||||
import suwayomi.tachidesk.model.table.CategoryTable
|
||||
import suwayomi.tachidesk.model.table.MangaTable
|
||||
import suwayomi.tachidesk.model.table.toDataClass
|
||||
import suwayomi.tachidesk.model.dataclass.CategoryDataClass
|
||||
import suwayomi.tachidesk.model.dataclass.MangaDataClass
|
||||
|
||||
|
||||
@@ -19,10 +19,10 @@ import org.jetbrains.exposed.sql.update
|
||||
import suwayomi.tachidesk.impl.Manga.getManga
|
||||
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
|
||||
import suwayomi.tachidesk.impl.util.lang.awaitSingle
|
||||
import suwayomi.tachidesk.model.database.table.ChapterTable
|
||||
import suwayomi.tachidesk.model.database.table.MangaTable
|
||||
import suwayomi.tachidesk.model.database.table.PageTable
|
||||
import suwayomi.tachidesk.model.database.table.toDataClass
|
||||
import suwayomi.tachidesk.model.table.ChapterTable
|
||||
import suwayomi.tachidesk.model.table.MangaTable
|
||||
import suwayomi.tachidesk.model.table.PageTable
|
||||
import suwayomi.tachidesk.model.table.toDataClass
|
||||
import suwayomi.tachidesk.model.dataclass.ChapterDataClass
|
||||
|
||||
object Chapter {
|
||||
|
||||
@@ -14,10 +14,10 @@ import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import org.jetbrains.exposed.sql.update
|
||||
import suwayomi.tachidesk.impl.Manga.getManga
|
||||
import suwayomi.tachidesk.model.database.table.CategoryMangaTable
|
||||
import suwayomi.tachidesk.model.database.table.CategoryTable
|
||||
import suwayomi.tachidesk.model.database.table.MangaTable
|
||||
import suwayomi.tachidesk.model.database.table.toDataClass
|
||||
import suwayomi.tachidesk.model.table.CategoryMangaTable
|
||||
import suwayomi.tachidesk.model.table.CategoryTable
|
||||
import suwayomi.tachidesk.model.table.MangaTable
|
||||
import suwayomi.tachidesk.model.table.toDataClass
|
||||
import suwayomi.tachidesk.model.dataclass.MangaDataClass
|
||||
|
||||
object Library {
|
||||
|
||||
@@ -23,8 +23,8 @@ import suwayomi.tachidesk.impl.util.lang.awaitSingle
|
||||
import suwayomi.tachidesk.impl.util.network.await
|
||||
import suwayomi.tachidesk.impl.util.storage.CachedImageResponse.clearCachedImage
|
||||
import suwayomi.tachidesk.impl.util.storage.CachedImageResponse.getCachedImageResponse
|
||||
import suwayomi.tachidesk.model.database.table.MangaStatus
|
||||
import suwayomi.tachidesk.model.database.table.MangaTable
|
||||
import suwayomi.tachidesk.model.table.MangaStatus
|
||||
import suwayomi.tachidesk.model.table.MangaTable
|
||||
import suwayomi.tachidesk.model.dataclass.MangaDataClass
|
||||
import java.io.InputStream
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
|
||||
import suwayomi.tachidesk.impl.util.lang.awaitSingle
|
||||
import suwayomi.tachidesk.model.database.table.MangaStatus
|
||||
import suwayomi.tachidesk.model.database.table.MangaTable
|
||||
import suwayomi.tachidesk.model.table.MangaStatus
|
||||
import suwayomi.tachidesk.model.table.MangaTable
|
||||
import suwayomi.tachidesk.model.dataclass.MangaDataClass
|
||||
import suwayomi.tachidesk.model.dataclass.PagedMangaListDataClass
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@ import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
|
||||
import suwayomi.tachidesk.impl.util.lang.awaitSingle
|
||||
import suwayomi.tachidesk.impl.util.storage.CachedImageResponse.getCachedImageResponse
|
||||
import suwayomi.tachidesk.impl.util.storage.SafePath
|
||||
import suwayomi.tachidesk.model.database.table.ChapterTable
|
||||
import suwayomi.tachidesk.model.database.table.MangaTable
|
||||
import suwayomi.tachidesk.model.database.table.PageTable
|
||||
import suwayomi.tachidesk.model.table.ChapterTable
|
||||
import suwayomi.tachidesk.model.table.MangaTable
|
||||
import suwayomi.tachidesk.model.table.PageTable
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ import org.jetbrains.exposed.sql.selectAll
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.impl.extension.Extension.getExtensionIconUrl
|
||||
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
|
||||
import suwayomi.tachidesk.model.database.table.ExtensionTable
|
||||
import suwayomi.tachidesk.model.database.table.SourceTable
|
||||
import suwayomi.tachidesk.model.table.ExtensionTable
|
||||
import suwayomi.tachidesk.model.table.SourceTable
|
||||
import suwayomi.tachidesk.model.dataclass.SourceDataClass
|
||||
|
||||
object Source {
|
||||
|
||||
@@ -24,8 +24,8 @@ import suwayomi.tachidesk.impl.backup.models.ChapterImpl
|
||||
import suwayomi.tachidesk.impl.backup.models.Manga
|
||||
import suwayomi.tachidesk.impl.backup.models.MangaImpl
|
||||
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
|
||||
import suwayomi.tachidesk.model.database.table.ChapterTable
|
||||
import suwayomi.tachidesk.model.database.table.MangaTable
|
||||
import suwayomi.tachidesk.model.table.ChapterTable
|
||||
import suwayomi.tachidesk.model.table.MangaTable
|
||||
|
||||
object LegacyBackupExport : LegacyBackupBase() {
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import suwayomi.tachidesk.impl.backup.models.Track
|
||||
import suwayomi.tachidesk.impl.backup.models.TrackImpl
|
||||
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
|
||||
import suwayomi.tachidesk.impl.util.lang.awaitSingle
|
||||
import suwayomi.tachidesk.model.database.table.MangaTable
|
||||
import suwayomi.tachidesk.model.table.MangaTable
|
||||
import java.io.InputStream
|
||||
import java.util.Date
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import com.google.gson.JsonObject
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.impl.backup.legacy.models.Backup
|
||||
import suwayomi.tachidesk.model.database.table.SourceTable
|
||||
import suwayomi.tachidesk.model.table.SourceTable
|
||||
|
||||
object LegacyBackupValidator {
|
||||
data class ValidationResult(val missingSources: List<String>, val missingTrackers: List<String>)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package suwayomi.tachidesk.impl.backup.models
|
||||
|
||||
import org.jetbrains.exposed.sql.ResultRow
|
||||
import suwayomi.tachidesk.model.database.table.ChapterTable
|
||||
import suwayomi.tachidesk.model.table.ChapterTable
|
||||
|
||||
class ChapterImpl : Chapter {
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package suwayomi.tachidesk.impl.backup.models
|
||||
|
||||
import org.jetbrains.exposed.sql.ResultRow
|
||||
import suwayomi.tachidesk.model.database.table.MangaTable
|
||||
import suwayomi.tachidesk.model.table.MangaTable
|
||||
|
||||
open class MangaImpl : Manga {
|
||||
|
||||
|
||||
@@ -40,8 +40,8 @@ import suwayomi.tachidesk.impl.util.PackageTools.loadExtensionSources
|
||||
import suwayomi.tachidesk.impl.util.PackageTools.trustedSignatures
|
||||
import suwayomi.tachidesk.impl.util.network.await
|
||||
import suwayomi.tachidesk.impl.util.storage.CachedImageResponse.getCachedImageResponse
|
||||
import suwayomi.tachidesk.model.database.table.ExtensionTable
|
||||
import suwayomi.tachidesk.model.database.table.SourceTable
|
||||
import suwayomi.tachidesk.model.table.ExtensionTable
|
||||
import suwayomi.tachidesk.model.table.SourceTable
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
|
||||
@@ -17,7 +17,7 @@ import org.jetbrains.exposed.sql.update
|
||||
import suwayomi.tachidesk.impl.extension.Extension.getExtensionIconUrl
|
||||
import suwayomi.tachidesk.impl.extension.github.ExtensionGithubApi
|
||||
import suwayomi.tachidesk.impl.extension.github.OnlineExtension
|
||||
import suwayomi.tachidesk.model.database.table.ExtensionTable
|
||||
import suwayomi.tachidesk.model.table.ExtensionTable
|
||||
import suwayomi.tachidesk.model.dataclass.ExtensionDataClass
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ import org.kodein.di.conf.global
|
||||
import org.kodein.di.instance
|
||||
import suwayomi.server.ApplicationDirs
|
||||
import suwayomi.tachidesk.impl.util.PackageTools.loadExtensionSources
|
||||
import suwayomi.tachidesk.model.database.table.ExtensionTable
|
||||
import suwayomi.tachidesk.model.database.table.SourceTable
|
||||
import suwayomi.tachidesk.model.table.ExtensionTable
|
||||
import suwayomi.tachidesk.model.table.SourceTable
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
object GetHttpSource {
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package suwayomi.tachidesk.model.database
|
||||
|
||||
/*
|
||||
* 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 org.jetbrains.exposed.sql.Database
|
||||
import org.kodein.di.DI
|
||||
import org.kodein.di.conf.global
|
||||
import org.kodein.di.instance
|
||||
import suwayomi.server.ApplicationDirs
|
||||
import suwayomi.tachidesk.model.database.migration.lib.loadMigrationsFrom
|
||||
import suwayomi.tachidesk.model.database.migration.lib.runMigrations
|
||||
|
||||
object DBManager {
|
||||
val db by lazy {
|
||||
val applicationDirs by DI.global.instance<ApplicationDirs>()
|
||||
Database.connect("jdbc:h2:${applicationDirs.dataRoot}/database", "org.h2.Driver")
|
||||
}
|
||||
}
|
||||
|
||||
fun databaseUp() {
|
||||
// must mention db object so the lazy block executes
|
||||
val db = DBManager.db
|
||||
db.useNestedTransactions = true
|
||||
|
||||
val migrations = loadMigrationsFrom("suwayomi.tachidesk.model.database.migration")
|
||||
runMigrations(migrations)
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
package suwayomi.tachidesk.model.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 eu.kanade.tachiyomi.source.model.SManga
|
||||
import org.jetbrains.exposed.dao.id.IdTable
|
||||
import org.jetbrains.exposed.dao.id.IntIdTable
|
||||
import org.jetbrains.exposed.sql.SchemaUtils
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.model.database.migration.lib.Migration
|
||||
|
||||
@Suppress("ClassName", "unused")
|
||||
class M0001_Initial : Migration() {
|
||||
private class ExtensionTable : IntIdTable() {
|
||||
init {
|
||||
varchar("apk_name", 1024)
|
||||
// default is the local source icon from tachiyomi
|
||||
varchar("icon_url", 2048)
|
||||
.default("https://raw.githubusercontent.com/tachiyomiorg/tachiyomi/64ba127e7d43b1d7e6d58a6f5c9b2bd5fe0543f7/app/src/main/res/mipmap-xxxhdpi/ic_local_source.webp")
|
||||
varchar("name", 128)
|
||||
varchar("pkg_name", 128)
|
||||
varchar("version_name", 16)
|
||||
integer("version_code")
|
||||
varchar("lang", 10)
|
||||
bool("is_nsfw")
|
||||
|
||||
bool("is_installed").default(false)
|
||||
bool("has_update").default(false)
|
||||
bool("is_obsolete").default(false)
|
||||
|
||||
varchar("class_name", 1024).default("") // fully qualified name
|
||||
}
|
||||
}
|
||||
|
||||
private class SourceTable(extensionTable: ExtensionTable) : IdTable<Long>() {
|
||||
override val id = long("id").entityId()
|
||||
init {
|
||||
varchar("name", 128)
|
||||
varchar("lang", 10)
|
||||
reference("extension", extensionTable)
|
||||
bool("part_of_factory_source").default(false)
|
||||
}
|
||||
}
|
||||
|
||||
private class MangaTable : IntIdTable() {
|
||||
init {
|
||||
varchar("url", 2048)
|
||||
varchar("title", 512)
|
||||
bool("initialized").default(false)
|
||||
|
||||
varchar("artist", 64).nullable()
|
||||
varchar("author", 64).nullable()
|
||||
varchar("description", 4096).nullable()
|
||||
varchar("genre", 1024).nullable()
|
||||
|
||||
// val status = enumeration("status", MangaStatus::class).default(MangaStatus.UNKNOWN)
|
||||
integer("status").default(SManga.UNKNOWN)
|
||||
varchar("thumbnail_url", 2048).nullable()
|
||||
|
||||
bool("in_library").default(false)
|
||||
bool("default_category").default(true)
|
||||
|
||||
// source is used by some ancestor of IntIdTable
|
||||
long("source")
|
||||
}
|
||||
}
|
||||
|
||||
private class ChapterTable(mangaTable: MangaTable) : IntIdTable() {
|
||||
init {
|
||||
varchar("url", 2048)
|
||||
varchar("name", 512)
|
||||
long("date_upload").default(0)
|
||||
float("chapter_number").default(-1f)
|
||||
varchar("scanlator", 128).nullable()
|
||||
|
||||
bool("read").default(false)
|
||||
bool("bookmark").default(false)
|
||||
integer("last_page_read").default(0)
|
||||
|
||||
integer("number_in_list")
|
||||
reference("manga", mangaTable)
|
||||
}
|
||||
}
|
||||
|
||||
private class PageTable(chapterTable: ChapterTable) : IntIdTable() {
|
||||
init {
|
||||
integer("index")
|
||||
varchar("url", 2048)
|
||||
varchar("imageUrl", 2048).nullable()
|
||||
reference("chapter", chapterTable)
|
||||
}
|
||||
}
|
||||
|
||||
private class CategoryTable : IntIdTable() {
|
||||
init {
|
||||
varchar("name", 64)
|
||||
bool("is_landing").default(false)
|
||||
integer("order").default(0)
|
||||
}
|
||||
}
|
||||
|
||||
private class CategoryMangaTable(categoryTable: CategoryTable, mangaTable: MangaTable) : IntIdTable() {
|
||||
init {
|
||||
reference("category", categoryTable)
|
||||
reference("manga", mangaTable)
|
||||
}
|
||||
}
|
||||
|
||||
/** initial migration, create all tables */
|
||||
override fun run() {
|
||||
transaction {
|
||||
val extensionTable = ExtensionTable()
|
||||
val sourceTable = SourceTable(extensionTable)
|
||||
val mangaTable = MangaTable()
|
||||
val chapterTable = ChapterTable(mangaTable)
|
||||
val pageTable = PageTable(chapterTable)
|
||||
val categoryTable = CategoryTable()
|
||||
val categoryMangaTable = CategoryMangaTable(categoryTable, mangaTable)
|
||||
SchemaUtils.create(
|
||||
extensionTable,
|
||||
sourceTable,
|
||||
mangaTable,
|
||||
chapterTable,
|
||||
pageTable,
|
||||
categoryTable,
|
||||
categoryMangaTable,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package suwayomi.tachidesk.model.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 org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||
import org.jetbrains.exposed.sql.vendors.currentDialect
|
||||
import suwayomi.tachidesk.model.database.migration.lib.Migration
|
||||
|
||||
@Suppress("ClassName", "unused")
|
||||
class M0002_ChapterTableIndexRename : Migration() {
|
||||
/** this migration renamed ChapterTable.NUMBER_IN_LIST to ChapterTable.INDEX */
|
||||
override fun run() {
|
||||
with(TransactionManager.current()) {
|
||||
exec("ALTER TABLE CHAPTER ALTER COLUMN NUMBER_IN_LIST RENAME TO INDEX")
|
||||
commit()
|
||||
currentDialect.resetCaches()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package suwayomi.tachidesk.model.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 org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||
import org.jetbrains.exposed.sql.vendors.currentDialect
|
||||
import suwayomi.tachidesk.model.database.migration.lib.Migration
|
||||
|
||||
@Suppress("ClassName", "unused")
|
||||
class M0003_DefaultCategory : Migration() {
|
||||
/** this migration renamed CategoryTable.IS_LANDING to ChapterTable.IS_DEFAULT */
|
||||
override fun run() {
|
||||
with(TransactionManager.current()) {
|
||||
exec("ALTER TABLE CATEGORY ALTER COLUMN IS_LANDING RENAME TO IS_DEFAULT")
|
||||
commit()
|
||||
currentDialect.resetCaches()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.model.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.model.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.model.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.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("/" + "suwayomi.tachidesk.model.database.migration".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
|
||||
}
|
||||
@@ -7,7 +7,7 @@ package suwayomi.tachidesk.model.dataclass
|
||||
* 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 suwayomi.tachidesk.model.database.table.MangaStatus
|
||||
import suwayomi.tachidesk.model.table.MangaStatus
|
||||
|
||||
data class MangaDataClass(
|
||||
val id: Int,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package suwayomi.tachidesk.model.database.table
|
||||
package suwayomi.tachidesk.model.table
|
||||
|
||||
/*
|
||||
* Copyright (C) Contributors to the Suwayomi project
|
||||
@@ -1,4 +1,4 @@
|
||||
package suwayomi.tachidesk.model.database.table
|
||||
package suwayomi.tachidesk.model.table
|
||||
|
||||
/*
|
||||
* Copyright (C) Contributors to the Suwayomi project
|
||||
@@ -1,4 +1,4 @@
|
||||
package suwayomi.tachidesk.model.database.table
|
||||
package suwayomi.tachidesk.model.table
|
||||
|
||||
/*
|
||||
* Copyright (C) Contributors to the Suwayomi project
|
||||
@@ -1,4 +1,4 @@
|
||||
package suwayomi.tachidesk.model.database.table
|
||||
package suwayomi.tachidesk.model.table
|
||||
|
||||
/*
|
||||
* Copyright (C) Contributors to the Suwayomi project
|
||||
@@ -1,4 +1,4 @@
|
||||
package suwayomi.tachidesk.model.database.table
|
||||
package suwayomi.tachidesk.model.table
|
||||
|
||||
/*
|
||||
* Copyright (C) Contributors to the Suwayomi project
|
||||
@@ -11,7 +11,7 @@ import eu.kanade.tachiyomi.source.model.SManga
|
||||
import org.jetbrains.exposed.dao.id.IntIdTable
|
||||
import org.jetbrains.exposed.sql.ResultRow
|
||||
import suwayomi.tachidesk.impl.MangaList.proxyThumbnailUrl
|
||||
import suwayomi.tachidesk.model.database.table.MangaStatus.Companion
|
||||
import suwayomi.tachidesk.model.table.MangaStatus.Companion
|
||||
import suwayomi.tachidesk.model.dataclass.MangaDataClass
|
||||
|
||||
object MangaTable : IntIdTable() {
|
||||
@@ -1,4 +1,4 @@
|
||||
package suwayomi.tachidesk.model.database.table
|
||||
package suwayomi.tachidesk.model.table
|
||||
|
||||
/*
|
||||
* Copyright (C) Contributors to the Suwayomi project
|
||||
@@ -1,4 +1,4 @@
|
||||
package suwayomi.tachidesk.model.database.table
|
||||
package suwayomi.tachidesk.model.table
|
||||
|
||||
/*
|
||||
* Copyright (C) Contributors to the Suwayomi project
|
||||
Reference in New Issue
Block a user