Skip to content

Commit 4dcd80d

Browse files
committed
chore: replace manual DB updates with Flyway migrations
1 parent 84c5ddc commit 4dcd80d

File tree

14 files changed

+141
-160
lines changed

14 files changed

+141
-160
lines changed

README.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,6 @@ Yes, you can use your synchronization server in the application by specifying it
3939

4040
## Installation
4141

42-
### MySQL schema
43-
44-
Before deploying the sync server, you have to run the SQL script to set up the schema for your MySQL database:
45-
46-
```shell
47-
mysql -h hostname -u user database < ./database.sql
48-
```
49-
5042
### Docker
5143

5244
Build image container:

build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ plugins {
22
alias(libs.plugins.kotlin.jvm)
33
alias(libs.plugins.ktor)
44
alias(libs.plugins.kotlin.plugin.serialization)
5+
alias(libs.plugins.flyway)
56
}
67

78
group = "org.kotatsu"
@@ -31,6 +32,8 @@ dependencies {
3132
implementation(libs.ktor.server.auto.head.response)
3233
implementation(libs.ktorm.core)
3334
implementation(libs.ktorm.support.mysql)
35+
implementation(libs.flyway.core)
36+
implementation(libs.flyway.mysql)
3437
implementation(libs.hikaricp)
3538
implementation(libs.mysql.connector.j)
3639
implementation(libs.mariadb.java.client)

database.sql

Lines changed: 0 additions & 134 deletions
This file was deleted.

gradle/libs.versions.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ kotlin-version = "2.2.0"
33
ktor-version = "3.2.2"
44
ktorm-version = "4.1.1"
55
logback-version = "1.5.18"
6+
flyway = "11.10.3"
67

78
[libraries]
89
ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor-version" }
@@ -15,6 +16,8 @@ ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor-
1516
ktor-server-content-negotiation = { module = "io.ktor:ktor-server-content-negotiation", version.ref = "ktor-version" }
1617
ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor-version" }
1718
ktor-server-status-pages = { module = "io.ktor:ktor-server-status-pages", version.ref = "ktor-version" }
19+
flyway-core = { module = "org.flywaydb:flyway-core", version.ref = "flyway" }
20+
flyway-mysql = { module = "org.flywaydb:flyway-mysql", version.ref = "flyway" }
1821

1922
ktorm-core = { module = "org.ktorm:ktorm-core", version.ref = "ktorm-version" }
2023
ktorm-support-mysql = { module = "org.ktorm:ktorm-support-mysql", version.ref = "ktorm-version" }
@@ -31,3 +34,4 @@ kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version
3134
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin-version" }
3235
ktor = { id = "io.ktor.plugin", version.ref = "ktor-version" }
3336
kotlin-plugin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin-version" }
37+
flyway = { id = "org.flywaydb.flyway", version.ref = "flyway"}

src/main/kotlin/org/kotatsu/Application.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ lateinit var database: Database
1111
fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)
1212

1313
fun Application.module() {
14+
runMigrations()
1415
configureSerialization()
1516
configureDatabase()
1617
configureAuthentication()

src/main/kotlin/org/kotatsu/model/user/UserEntity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import org.ktorm.entity.Entity
55
interface UserEntity : Entity<UserEntity> {
66
var id: Int
77
var email: String
8-
var password: String
8+
var passwordHash: String
99
var nickname: String?
1010
var favouritesSyncTimestamp: Long?
1111
var historySyncTimestamp: Long?

src/main/kotlin/org/kotatsu/model/user/UsersTable.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import org.ktorm.schema.varchar
88
object UsersTable : Table<UserEntity>("users") {
99
val id = int("id").primaryKey().bindTo { it.id }
1010
val email = varchar("email").bindTo { it.email }
11-
val password = varchar("password").bindTo { it.password }
11+
val passwordHash = varchar("password_hash").bindTo { it.passwordHash }
1212
val nickname = varchar("nickname").bindTo { it.nickname }
1313
val favouritesSyncTimestamp = long("favourites_sync_timestamp").bindTo { it.favouritesSyncTimestamp }
1414
val historySyncTimestamp = long("history_sync_timestamp").bindTo { it.historySyncTimestamp }
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.kotatsu.plugins
2+
3+
import io.ktor.server.application.*
4+
import org.flywaydb.core.Flyway
5+
6+
fun Application.runMigrations() {
7+
val dbConfig = environment.config.config("database")
8+
9+
val host = dbConfig.property("host").getString()
10+
val port = dbConfig.property("port").getString()
11+
val dbName = dbConfig.property("name").getString()
12+
val user = dbConfig.property("user").getString()
13+
val password = dbConfig.property("password").getString()
14+
15+
val flyway = Flyway.configure()
16+
.dataSource("jdbc:mysql://$host:$port/$dbName", user, password)
17+
.load()
18+
19+
flyway.migrate()
20+
}

src/main/kotlin/org/kotatsu/resources/Manga.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ suspend fun Database.upsertManga(manga: Manga) {
2020
withRetry {
2121
insertOrUpdate(MangaTable) {
2222
set(it.id, manga.id)
23-
set(it.title, manga.title.truncated(84))
24-
set(it.altTitle, manga.altTitle?.truncated(84))
23+
set(it.title, manga.title.truncated(100))
24+
set(it.altTitle, manga.altTitle?.truncated(100))
2525
set(it.url, manga.url.truncated(255))
2626
set(it.publicUrl, manga.publicUrl.truncated(255))
2727
set(it.rating, manga.rating)
@@ -32,8 +32,8 @@ suspend fun Database.upsertManga(manga: Manga) {
3232
set(it.author, manga.author?.truncated(64))
3333
set(it.mangaSource, manga.source.truncated(32))
3434
onDuplicateKey {
35-
set(it.title, manga.title.truncated(84))
36-
set(it.altTitle, manga.altTitle?.truncated(84))
35+
set(it.title, manga.title.truncated(100))
36+
set(it.altTitle, manga.altTitle?.truncated(100))
3737
set(it.url, manga.url.truncated(255))
3838
set(it.publicUrl, manga.publicUrl.truncated(255))
3939
set(it.rating, manga.rating)

src/main/kotlin/org/kotatsu/resources/User.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,23 @@ suspend fun getOrCreateUser(request: AuthRequest, allowNewRegister: Boolean): Us
1414
require(request.password.length in 2..24) {
1515
"Password should be from 2 to 24 characters long"
1616
}
17-
require(request.email.length in 5..120 && '@' in request.email) {
17+
require(request.email.length in 5..320 && '@' in request.email) {
1818
"Invalid email address"
1919
}
2020
val passDigest = request.password.md5()
2121
val user = database.users.find { (it.email eq request.email) }
2222
when {
2323
user == null && allowNewRegister -> registerUser(request, passDigest)
2424
user == null -> null
25-
user.password == passDigest -> user.toUserInfo()
25+
user.passwordHash == passDigest -> user.toUserInfo()
2626
else -> null
2727
}
2828
}
2929

3030
private fun registerUser(request: AuthRequest, passwordDigest: String): UserInfo? {
3131
val userId = database.insertAndGenerateKey(UsersTable) {
3232
set(it.email, request.email)
33-
set(it.password, passwordDigest)
33+
set(it.passwordHash, passwordDigest)
3434
set(it.nickname, null)
3535
set(it.favouritesSyncTimestamp, null)
3636
set(it.historySyncTimestamp, null)

0 commit comments

Comments
 (0)