mirror of
https://github.com/tachiyomiorg/tachiyomi-extensions-inspector.git
synced 2025-01-25 23:11:17 +01:00
Add migrations (#76)
This commit is contained in:
parent
5304917e53
commit
63a078cf7d
@ -20,9 +20,6 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
|
|
||||||
implementation(kotlin("stdlib-jdk8"))
|
|
||||||
|
|
||||||
// Source models and interfaces from Tachiyomi 1.x
|
// Source models and interfaces from Tachiyomi 1.x
|
||||||
// using source class from tachiyomi commit 9493577de27c40ce8b2b6122cc447d025e34c477 to not depend on tachiyomi.sourceapi
|
// using source class from tachiyomi commit 9493577de27c40ce8b2b6122cc447d025e34c477 to not depend on tachiyomi.sourceapi
|
||||||
// implementation("tachiyomi.sourceapi:source-api:1.1")
|
// implementation("tachiyomi.sourceapi:source-api:1.1")
|
||||||
@ -47,7 +44,7 @@ dependencies {
|
|||||||
// Reactivex
|
// Reactivex
|
||||||
implementation("io.reactivex:rxjava:1.3.8")
|
implementation("io.reactivex:rxjava:1.3.8")
|
||||||
|
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.0")
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0")
|
||||||
implementation("com.google.code.gson:gson:2.8.6")
|
implementation("com.google.code.gson:gson:2.8.6")
|
||||||
implementation("com.github.salomonbrys.kotson:kotson:2.5.0")
|
implementation("com.github.salomonbrys.kotson:kotson:2.5.0")
|
||||||
|
|
||||||
@ -64,12 +61,16 @@ dependencies {
|
|||||||
implementation("org.jetbrains.exposed:exposed-core:$exposedVersion")
|
implementation("org.jetbrains.exposed:exposed-core:$exposedVersion")
|
||||||
implementation("org.jetbrains.exposed:exposed-dao:$exposedVersion")
|
implementation("org.jetbrains.exposed:exposed-dao:$exposedVersion")
|
||||||
implementation("org.jetbrains.exposed:exposed-jdbc:$exposedVersion")
|
implementation("org.jetbrains.exposed:exposed-jdbc:$exposedVersion")
|
||||||
|
implementation("org.jetbrains.exposed:exposed-java-time:$exposedVersion")
|
||||||
|
|
||||||
|
// current database driver
|
||||||
implementation("com.h2database:h2:1.4.200")
|
implementation("com.h2database:h2:1.4.200")
|
||||||
|
|
||||||
// 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")
|
||||||
|
|
||||||
|
implementation("com.google.guava:guava:30.1.1-jre")
|
||||||
|
|
||||||
// AndroidCompat
|
// AndroidCompat
|
||||||
implementation(project(":AndroidCompat"))
|
implementation(project(":AndroidCompat"))
|
||||||
|
@ -8,9 +8,9 @@ package ir.armor.tachidesk.impl
|
|||||||
* 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 ir.armor.tachidesk.impl.CategoryManga.removeMangaFromCategory
|
import ir.armor.tachidesk.impl.CategoryManga.removeMangaFromCategory
|
||||||
import ir.armor.tachidesk.model.database.CategoryMangaTable
|
import ir.armor.tachidesk.model.database.table.CategoryMangaTable
|
||||||
import ir.armor.tachidesk.model.database.CategoryTable
|
import ir.armor.tachidesk.model.database.table.CategoryTable
|
||||||
import ir.armor.tachidesk.model.database.toDataClass
|
import ir.armor.tachidesk.model.database.table.toDataClass
|
||||||
import ir.armor.tachidesk.model.dataclass.CategoryDataClass
|
import ir.armor.tachidesk.model.dataclass.CategoryDataClass
|
||||||
import org.jetbrains.exposed.sql.SortOrder
|
import org.jetbrains.exposed.sql.SortOrder
|
||||||
import org.jetbrains.exposed.sql.deleteWhere
|
import org.jetbrains.exposed.sql.deleteWhere
|
||||||
|
@ -7,10 +7,10 @@ package ir.armor.tachidesk.impl
|
|||||||
* 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 ir.armor.tachidesk.model.database.CategoryMangaTable
|
import ir.armor.tachidesk.model.database.table.CategoryMangaTable
|
||||||
import ir.armor.tachidesk.model.database.CategoryTable
|
import ir.armor.tachidesk.model.database.table.CategoryTable
|
||||||
import ir.armor.tachidesk.model.database.MangaTable
|
import ir.armor.tachidesk.model.database.table.MangaTable
|
||||||
import ir.armor.tachidesk.model.database.toDataClass
|
import ir.armor.tachidesk.model.database.table.toDataClass
|
||||||
import ir.armor.tachidesk.model.dataclass.CategoryDataClass
|
import ir.armor.tachidesk.model.dataclass.CategoryDataClass
|
||||||
import ir.armor.tachidesk.model.dataclass.MangaDataClass
|
import ir.armor.tachidesk.model.dataclass.MangaDataClass
|
||||||
import org.jetbrains.exposed.sql.SortOrder
|
import org.jetbrains.exposed.sql.SortOrder
|
||||||
|
@ -12,9 +12,9 @@ import eu.kanade.tachiyomi.source.model.SManga
|
|||||||
import ir.armor.tachidesk.impl.Manga.getManga
|
import ir.armor.tachidesk.impl.Manga.getManga
|
||||||
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
|
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
|
||||||
import ir.armor.tachidesk.impl.util.awaitSingle
|
import ir.armor.tachidesk.impl.util.awaitSingle
|
||||||
import ir.armor.tachidesk.model.database.ChapterTable
|
import ir.armor.tachidesk.model.database.table.ChapterTable
|
||||||
import ir.armor.tachidesk.model.database.MangaTable
|
import ir.armor.tachidesk.model.database.table.MangaTable
|
||||||
import ir.armor.tachidesk.model.database.PageTable
|
import ir.armor.tachidesk.model.database.table.PageTable
|
||||||
import ir.armor.tachidesk.model.dataclass.ChapterDataClass
|
import ir.armor.tachidesk.model.dataclass.ChapterDataClass
|
||||||
import org.jetbrains.exposed.sql.and
|
import org.jetbrains.exposed.sql.and
|
||||||
import org.jetbrains.exposed.sql.insert
|
import org.jetbrains.exposed.sql.insert
|
||||||
|
@ -27,8 +27,8 @@ import ir.armor.tachidesk.impl.util.PackageTools.getSignatureHash
|
|||||||
import ir.armor.tachidesk.impl.util.PackageTools.loadExtensionSources
|
import ir.armor.tachidesk.impl.util.PackageTools.loadExtensionSources
|
||||||
import ir.armor.tachidesk.impl.util.PackageTools.trustedSignatures
|
import ir.armor.tachidesk.impl.util.PackageTools.trustedSignatures
|
||||||
import ir.armor.tachidesk.impl.util.await
|
import ir.armor.tachidesk.impl.util.await
|
||||||
import ir.armor.tachidesk.model.database.ExtensionTable
|
import ir.armor.tachidesk.model.database.table.ExtensionTable
|
||||||
import ir.armor.tachidesk.model.database.SourceTable
|
import ir.armor.tachidesk.model.database.table.SourceTable
|
||||||
import ir.armor.tachidesk.server.ApplicationDirs
|
import ir.armor.tachidesk.server.ApplicationDirs
|
||||||
import mu.KotlinLogging
|
import mu.KotlinLogging
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
|
@ -10,7 +10,7 @@ package ir.armor.tachidesk.impl
|
|||||||
import eu.kanade.tachiyomi.extension.api.ExtensionGithubApi
|
import eu.kanade.tachiyomi.extension.api.ExtensionGithubApi
|
||||||
import eu.kanade.tachiyomi.extension.model.Extension
|
import eu.kanade.tachiyomi.extension.model.Extension
|
||||||
import ir.armor.tachidesk.impl.Extension.getExtensionIconUrl
|
import ir.armor.tachidesk.impl.Extension.getExtensionIconUrl
|
||||||
import ir.armor.tachidesk.model.database.ExtensionTable
|
import ir.armor.tachidesk.model.database.table.ExtensionTable
|
||||||
import ir.armor.tachidesk.model.dataclass.ExtensionDataClass
|
import ir.armor.tachidesk.model.dataclass.ExtensionDataClass
|
||||||
import mu.KotlinLogging
|
import mu.KotlinLogging
|
||||||
import org.jetbrains.exposed.sql.deleteWhere
|
import org.jetbrains.exposed.sql.deleteWhere
|
||||||
|
@ -8,9 +8,9 @@ package ir.armor.tachidesk.impl
|
|||||||
* 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 ir.armor.tachidesk.impl.Manga.getManga
|
import ir.armor.tachidesk.impl.Manga.getManga
|
||||||
import ir.armor.tachidesk.model.database.CategoryMangaTable
|
import ir.armor.tachidesk.model.database.table.CategoryMangaTable
|
||||||
import ir.armor.tachidesk.model.database.MangaTable
|
import ir.armor.tachidesk.model.database.table.MangaTable
|
||||||
import ir.armor.tachidesk.model.database.toDataClass
|
import ir.armor.tachidesk.model.database.table.toDataClass
|
||||||
import ir.armor.tachidesk.model.dataclass.MangaDataClass
|
import ir.armor.tachidesk.model.dataclass.MangaDataClass
|
||||||
import org.jetbrains.exposed.sql.and
|
import org.jetbrains.exposed.sql.and
|
||||||
import org.jetbrains.exposed.sql.deleteWhere
|
import org.jetbrains.exposed.sql.deleteWhere
|
||||||
|
@ -15,8 +15,8 @@ import ir.armor.tachidesk.impl.util.CachedImageResponse.getCachedImageResponse
|
|||||||
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
|
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
|
||||||
import ir.armor.tachidesk.impl.util.await
|
import ir.armor.tachidesk.impl.util.await
|
||||||
import ir.armor.tachidesk.impl.util.awaitSingle
|
import ir.armor.tachidesk.impl.util.awaitSingle
|
||||||
import ir.armor.tachidesk.model.database.MangaStatus
|
import ir.armor.tachidesk.model.database.table.MangaStatus
|
||||||
import ir.armor.tachidesk.model.database.MangaTable
|
import ir.armor.tachidesk.model.database.table.MangaTable
|
||||||
import ir.armor.tachidesk.model.dataclass.MangaDataClass
|
import ir.armor.tachidesk.model.dataclass.MangaDataClass
|
||||||
import ir.armor.tachidesk.server.ApplicationDirs
|
import ir.armor.tachidesk.server.ApplicationDirs
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
|
@ -10,8 +10,8 @@ package ir.armor.tachidesk.impl
|
|||||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||||
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
|
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
|
||||||
import ir.armor.tachidesk.impl.util.awaitSingle
|
import ir.armor.tachidesk.impl.util.awaitSingle
|
||||||
import ir.armor.tachidesk.model.database.MangaStatus
|
import ir.armor.tachidesk.model.database.table.MangaStatus
|
||||||
import ir.armor.tachidesk.model.database.MangaTable
|
import ir.armor.tachidesk.model.database.table.MangaTable
|
||||||
import ir.armor.tachidesk.model.dataclass.MangaDataClass
|
import ir.armor.tachidesk.model.dataclass.MangaDataClass
|
||||||
import ir.armor.tachidesk.model.dataclass.PagedMangaListDataClass
|
import ir.armor.tachidesk.model.dataclass.PagedMangaListDataClass
|
||||||
import org.jetbrains.exposed.sql.insertAndGetId
|
import org.jetbrains.exposed.sql.insertAndGetId
|
||||||
|
@ -12,10 +12,10 @@ import eu.kanade.tachiyomi.source.online.HttpSource
|
|||||||
import ir.armor.tachidesk.impl.util.CachedImageResponse.getCachedImageResponse
|
import ir.armor.tachidesk.impl.util.CachedImageResponse.getCachedImageResponse
|
||||||
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
|
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
|
||||||
import ir.armor.tachidesk.impl.util.awaitSingle
|
import ir.armor.tachidesk.impl.util.awaitSingle
|
||||||
import ir.armor.tachidesk.model.database.ChapterTable
|
import ir.armor.tachidesk.model.database.table.ChapterTable
|
||||||
import ir.armor.tachidesk.model.database.MangaTable
|
import ir.armor.tachidesk.model.database.table.MangaTable
|
||||||
import ir.armor.tachidesk.model.database.PageTable
|
import ir.armor.tachidesk.model.database.table.PageTable
|
||||||
import ir.armor.tachidesk.model.database.SourceTable
|
import ir.armor.tachidesk.model.database.table.SourceTable
|
||||||
import ir.armor.tachidesk.server.ApplicationDirs
|
import ir.armor.tachidesk.server.ApplicationDirs
|
||||||
import org.jetbrains.exposed.sql.and
|
import org.jetbrains.exposed.sql.and
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
|
@ -9,8 +9,8 @@ package ir.armor.tachidesk.impl
|
|||||||
|
|
||||||
import ir.armor.tachidesk.impl.Extension.getExtensionIconUrl
|
import ir.armor.tachidesk.impl.Extension.getExtensionIconUrl
|
||||||
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
|
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
|
||||||
import ir.armor.tachidesk.model.database.ExtensionTable
|
import ir.armor.tachidesk.model.database.table.ExtensionTable
|
||||||
import ir.armor.tachidesk.model.database.SourceTable
|
import ir.armor.tachidesk.model.database.table.SourceTable
|
||||||
import ir.armor.tachidesk.model.dataclass.SourceDataClass
|
import ir.armor.tachidesk.model.dataclass.SourceDataClass
|
||||||
import mu.KotlinLogging
|
import mu.KotlinLogging
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
|
@ -22,8 +22,8 @@ import ir.armor.tachidesk.impl.backup.models.ChapterImpl
|
|||||||
import ir.armor.tachidesk.impl.backup.models.Manga
|
import ir.armor.tachidesk.impl.backup.models.Manga
|
||||||
import ir.armor.tachidesk.impl.backup.models.MangaImpl
|
import ir.armor.tachidesk.impl.backup.models.MangaImpl
|
||||||
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
|
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
|
||||||
import ir.armor.tachidesk.model.database.ChapterTable
|
import ir.armor.tachidesk.model.database.table.ChapterTable
|
||||||
import ir.armor.tachidesk.model.database.MangaTable
|
import ir.armor.tachidesk.model.database.table.MangaTable
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ import ir.armor.tachidesk.impl.backup.models.Track
|
|||||||
import ir.armor.tachidesk.impl.backup.models.TrackImpl
|
import ir.armor.tachidesk.impl.backup.models.TrackImpl
|
||||||
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
|
import ir.armor.tachidesk.impl.util.GetHttpSource.getHttpSource
|
||||||
import ir.armor.tachidesk.impl.util.awaitSingle
|
import ir.armor.tachidesk.impl.util.awaitSingle
|
||||||
import ir.armor.tachidesk.model.database.MangaTable
|
import ir.armor.tachidesk.model.database.table.MangaTable
|
||||||
import mu.KotlinLogging
|
import mu.KotlinLogging
|
||||||
import org.jetbrains.exposed.sql.and
|
import org.jetbrains.exposed.sql.and
|
||||||
import org.jetbrains.exposed.sql.insert
|
import org.jetbrains.exposed.sql.insert
|
||||||
|
@ -9,7 +9,7 @@ package ir.armor.tachidesk.impl.backup.legacy
|
|||||||
|
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import ir.armor.tachidesk.impl.backup.legacy.models.Backup
|
import ir.armor.tachidesk.impl.backup.legacy.models.Backup
|
||||||
import ir.armor.tachidesk.model.database.SourceTable
|
import ir.armor.tachidesk.model.database.table.SourceTable
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package ir.armor.tachidesk.impl.backup.models
|
package ir.armor.tachidesk.impl.backup.models
|
||||||
|
|
||||||
import ir.armor.tachidesk.model.database.ChapterTable
|
import ir.armor.tachidesk.model.database.table.ChapterTable
|
||||||
import org.jetbrains.exposed.sql.ResultRow
|
import org.jetbrains.exposed.sql.ResultRow
|
||||||
|
|
||||||
class ChapterImpl : Chapter {
|
class ChapterImpl : Chapter {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package ir.armor.tachidesk.impl.backup.models
|
package ir.armor.tachidesk.impl.backup.models
|
||||||
|
|
||||||
import ir.armor.tachidesk.model.database.MangaTable
|
import ir.armor.tachidesk.model.database.table.MangaTable
|
||||||
import org.jetbrains.exposed.sql.ResultRow
|
import org.jetbrains.exposed.sql.ResultRow
|
||||||
|
|
||||||
open class MangaImpl : Manga {
|
open class MangaImpl : Manga {
|
||||||
|
@ -11,8 +11,8 @@ import eu.kanade.tachiyomi.source.Source
|
|||||||
import eu.kanade.tachiyomi.source.SourceFactory
|
import eu.kanade.tachiyomi.source.SourceFactory
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import ir.armor.tachidesk.impl.util.PackageTools.loadExtensionSources
|
import ir.armor.tachidesk.impl.util.PackageTools.loadExtensionSources
|
||||||
import ir.armor.tachidesk.model.database.ExtensionTable
|
import ir.armor.tachidesk.model.database.table.ExtensionTable
|
||||||
import ir.armor.tachidesk.model.database.SourceTable
|
import ir.armor.tachidesk.model.database.table.SourceTable
|
||||||
import ir.armor.tachidesk.server.ApplicationDirs
|
import ir.armor.tachidesk.server.ApplicationDirs
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
@ -7,10 +7,10 @@ package ir.armor.tachidesk.model.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 ir.armor.tachidesk.model.database.migration.lib.loadMigrationsFrom
|
||||||
|
import ir.armor.tachidesk.model.database.migration.lib.runMigrations
|
||||||
import ir.armor.tachidesk.server.ApplicationDirs
|
import ir.armor.tachidesk.server.ApplicationDirs
|
||||||
import org.jetbrains.exposed.sql.Database
|
import org.jetbrains.exposed.sql.Database
|
||||||
import org.jetbrains.exposed.sql.SchemaUtils
|
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
|
||||||
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
|
||||||
@ -22,20 +22,11 @@ object DBMangaer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun makeDataBaseTables() {
|
fun databaseUp() {
|
||||||
// must mention db object so the lazy block executes
|
// must mention db object so the lazy block executes
|
||||||
val db = DBMangaer.db
|
val db = DBMangaer.db
|
||||||
db.useNestedTransactions = true
|
db.useNestedTransactions = true
|
||||||
|
|
||||||
transaction {
|
val migrations = loadMigrationsFrom("ir.armor.tachidesk.model.database.migration")
|
||||||
SchemaUtils.createMissingTablesAndColumns(
|
runMigrations(migrations)
|
||||||
ExtensionTable,
|
|
||||||
SourceTable,
|
|
||||||
MangaTable,
|
|
||||||
ChapterTable,
|
|
||||||
PageTable,
|
|
||||||
CategoryTable,
|
|
||||||
CategoryMangaTable,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,117 @@
|
|||||||
|
package ir.armor.tachidesk.model.database.migration
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import ir.armor.tachidesk.model.database.migration.lib.Migration
|
||||||
|
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
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 M0001_Initial : Migration() {
|
||||||
|
private object ExtensionTable : IntIdTable() {
|
||||||
|
val apkName = varchar("apk_name", 1024)
|
||||||
|
|
||||||
|
// default is the local source icon from tachiyomi
|
||||||
|
val iconUrl = varchar("icon_url", 2048)
|
||||||
|
.default("https://raw.githubusercontent.com/tachiyomiorg/tachiyomi/64ba127e7d43b1d7e6d58a6f5c9b2bd5fe0543f7/app/src/main/res/mipmap-xxxhdpi/ic_local_source.webp")
|
||||||
|
|
||||||
|
val name = varchar("name", 128)
|
||||||
|
val pkgName = varchar("pkg_name", 128)
|
||||||
|
val versionName = varchar("version_name", 16)
|
||||||
|
val versionCode = integer("version_code")
|
||||||
|
val lang = varchar("lang", 10)
|
||||||
|
val isNsfw = bool("is_nsfw")
|
||||||
|
|
||||||
|
val isInstalled = bool("is_installed").default(false)
|
||||||
|
val hasUpdate = bool("has_update").default(false)
|
||||||
|
val isObsolete = bool("is_obsolete").default(false)
|
||||||
|
|
||||||
|
val classFQName = varchar("class_name", 1024).default("") // fully qualified name
|
||||||
|
}
|
||||||
|
|
||||||
|
private object SourceTable : IdTable<Long>() {
|
||||||
|
override val id = long("id").entityId()
|
||||||
|
val name = varchar("name", 128)
|
||||||
|
val lang = varchar("lang", 10)
|
||||||
|
val extension = reference("extension", ExtensionTable)
|
||||||
|
val partOfFactorySource = bool("part_of_factory_source").default(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private object MangaTable : IntIdTable() {
|
||||||
|
val url = varchar("url", 2048)
|
||||||
|
val title = varchar("title", 512)
|
||||||
|
val initialized = bool("initialized").default(false)
|
||||||
|
|
||||||
|
val artist = varchar("artist", 64).nullable()
|
||||||
|
val author = varchar("author", 64).nullable()
|
||||||
|
val description = varchar("description", 4096).nullable()
|
||||||
|
val genre = varchar("genre", 1024).nullable()
|
||||||
|
|
||||||
|
// val status = enumeration("status", MangaStatus::class).default(MangaStatus.UNKNOWN)
|
||||||
|
val status = integer("status").default(SManga.UNKNOWN)
|
||||||
|
val thumbnail_url = varchar("thumbnail_url", 2048).nullable()
|
||||||
|
|
||||||
|
val inLibrary = bool("in_library").default(false)
|
||||||
|
val defaultCategory = bool("default_category").default(true)
|
||||||
|
|
||||||
|
// source is used by some ancestor of IntIdTable
|
||||||
|
val sourceReference = long("source")
|
||||||
|
}
|
||||||
|
|
||||||
|
private object ChapterTable : IntIdTable() {
|
||||||
|
val url = varchar("url", 2048)
|
||||||
|
val name = varchar("name", 512)
|
||||||
|
val date_upload = long("date_upload").default(0)
|
||||||
|
val chapter_number = float("chapter_number").default(-1f)
|
||||||
|
val scanlator = varchar("scanlator", 128).nullable()
|
||||||
|
|
||||||
|
val isRead = bool("read").default(false)
|
||||||
|
val isBookmarked = bool("bookmark").default(false)
|
||||||
|
val lastPageRead = integer("last_page_read").default(0)
|
||||||
|
|
||||||
|
val chapterIndex = integer("number_in_list")
|
||||||
|
|
||||||
|
val manga = reference("manga", MangaTable)
|
||||||
|
}
|
||||||
|
|
||||||
|
private object PageTable : IntIdTable() {
|
||||||
|
val index = integer("index")
|
||||||
|
val url = varchar("url", 2048)
|
||||||
|
val imageUrl = varchar("imageUrl", 2048).nullable()
|
||||||
|
|
||||||
|
val chapter = reference("chapter", ChapterTable)
|
||||||
|
}
|
||||||
|
|
||||||
|
private object CategoryTable : IntIdTable() {
|
||||||
|
val name = varchar("name", 64)
|
||||||
|
val isLanding = bool("is_landing").default(false)
|
||||||
|
val order = integer("order").default(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private object CategoryMangaTable : IntIdTable() {
|
||||||
|
val category = reference("category", ir.armor.tachidesk.model.database.table.CategoryTable)
|
||||||
|
val manga = reference("manga", ir.armor.tachidesk.model.database.table.MangaTable)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun run() {
|
||||||
|
transaction {
|
||||||
|
SchemaUtils.create(
|
||||||
|
ExtensionTable,
|
||||||
|
ExtensionTable,
|
||||||
|
SourceTable,
|
||||||
|
MangaTable,
|
||||||
|
ChapterTable,
|
||||||
|
PageTable,
|
||||||
|
CategoryTable,
|
||||||
|
CategoryMangaTable,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
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.
|
@ -0,0 +1,25 @@
|
|||||||
|
package ir.armor.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()
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package ir.armor.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
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
package ir.armor.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 com.google.common.reflect.ClassPath
|
||||||
|
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 java.time.Clock
|
||||||
|
import java.time.Instant.now
|
||||||
|
|
||||||
|
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" }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadMigrationsFrom(classPath: String): List<Migration> {
|
||||||
|
return ClassPath.from(Thread.currentThread().contextClassLoader)
|
||||||
|
.getTopLevelClasses(classPath)
|
||||||
|
.map {
|
||||||
|
logger.debug("found Migration class ${it.name}")
|
||||||
|
val clazz = it.load().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
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package ir.armor.tachidesk.model.database
|
package ir.armor.tachidesk.model.database.table
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
@ -1,4 +1,4 @@
|
|||||||
package ir.armor.tachidesk.model.database
|
package ir.armor.tachidesk.model.database.table
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
@ -1,4 +1,4 @@
|
|||||||
package ir.armor.tachidesk.model.database
|
package ir.armor.tachidesk.model.database.table
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
@ -1,4 +1,4 @@
|
|||||||
package ir.armor.tachidesk.model.database
|
package ir.armor.tachidesk.model.database.table
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
@ -1,4 +1,4 @@
|
|||||||
package ir.armor.tachidesk.model.database
|
package ir.armor.tachidesk.model.database.table
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@ -37,7 +37,7 @@ object MangaTable : IntIdTable() {
|
|||||||
fun MangaTable.toDataClass(mangaEntry: ResultRow) =
|
fun MangaTable.toDataClass(mangaEntry: ResultRow) =
|
||||||
MangaDataClass(
|
MangaDataClass(
|
||||||
mangaEntry[MangaTable.id].value,
|
mangaEntry[MangaTable.id].value,
|
||||||
mangaEntry[sourceReference].toString(),
|
mangaEntry[MangaTable.sourceReference].toString(),
|
||||||
|
|
||||||
mangaEntry[MangaTable.url],
|
mangaEntry[MangaTable.url],
|
||||||
mangaEntry[MangaTable.title],
|
mangaEntry[MangaTable.title],
|
@ -1,4 +1,4 @@
|
|||||||
package ir.armor.tachidesk.model.database
|
package ir.armor.tachidesk.model.database.table
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
@ -1,4 +1,4 @@
|
|||||||
package ir.armor.tachidesk.model.database
|
package ir.armor.tachidesk.model.database.table
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
@ -7,7 +7,7 @@ package ir.armor.tachidesk.model.dataclass
|
|||||||
* 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 ir.armor.tachidesk.model.database.MangaStatus
|
import ir.armor.tachidesk.model.database.table.MangaStatus
|
||||||
|
|
||||||
data class MangaDataClass(
|
data class MangaDataClass(
|
||||||
val id: Int,
|
val id: Int,
|
||||||
|
@ -10,7 +10,7 @@ package ir.armor.tachidesk.server
|
|||||||
import ch.qos.logback.classic.Level
|
import ch.qos.logback.classic.Level
|
||||||
import eu.kanade.tachiyomi.App
|
import eu.kanade.tachiyomi.App
|
||||||
import ir.armor.tachidesk.Main
|
import ir.armor.tachidesk.Main
|
||||||
import ir.armor.tachidesk.model.database.makeDataBaseTables
|
import ir.armor.tachidesk.model.database.databaseUp
|
||||||
import ir.armor.tachidesk.server.util.systemTray
|
import ir.armor.tachidesk.server.util.systemTray
|
||||||
import mu.KotlinLogging
|
import mu.KotlinLogging
|
||||||
import org.kodein.di.DI
|
import org.kodein.di.DI
|
||||||
@ -91,7 +91,7 @@ fun applicationSetup() {
|
|||||||
logger.error("Exception while creating initial server.conf:\n", e)
|
logger.error("Exception while creating initial server.conf:\n", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
makeDataBaseTables()
|
databaseUp()
|
||||||
|
|
||||||
// create system tray
|
// create system tray
|
||||||
if (serverConfig.systemTrayEnabled) {
|
if (serverConfig.systemTrayEnabled) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user