Add SteamWar CLI module

- add Clikt-based `sw` entrypoint and subcommands
- include database, user, dev, and profiler commands
- wire CLI build and CI install/release steps
This commit is contained in:
2026-05-09 16:46:59 +02:00
parent 8ade5180cb
commit 1451750bcb
15 changed files with 581 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
package de.steamwar.db
import com.github.ajalt.clikt.core.BaseCliktCommand
import com.github.ajalt.clikt.core.CliktError
import de.steamwar.sql.SteamwarUser
import de.steamwar.sql.SteamwarUserTable
import org.jetbrains.exposed.v1.core.Expression
import org.jetbrains.exposed.v1.core.Op
import org.jetbrains.exposed.v1.core.eq
import org.jetbrains.exposed.v1.core.or
import org.jetbrains.exposed.v1.jdbc.Database
import org.jetbrains.exposed.v1.jdbc.JdbcTransaction
import org.jetbrains.exposed.v1.jdbc.transactions.transaction
import java.io.File
import java.sql.ResultSet
import java.util.Properties
object Database {
lateinit var host: String
lateinit var port: String
lateinit var database: String
lateinit var db: Database
fun ensureConnected() {
if (::db.isInitialized) {
return
}
val config = File(System.getProperty("user.home"), "mysql.properties")
if (!config.exists()) {
throw CliktError("Config file not found!")
}
val props = Properties();
props.load(config.inputStream())
host = props.getProperty("host")
port = props.getProperty("port")
database = props.getProperty("database")
val username = props.getProperty("user")
val password = props.getProperty("password")
val url = "jdbc:mariadb://$host:$port/$database"
db = Database.connect(url, driver = "org.mariadb.jdbc.Driver", user = username, password = password)
return
}
}
fun <T: BaseCliktCommand<T>> BaseCliktCommand<T>.findUser(query: String): SteamwarUser? = transaction {
SteamwarUser.find { joinedOr(query.toIntOrNull()?.let { SteamwarUserTable.id eq it }, (SteamwarUserTable.username eq query), SteamwarUserTable.uuid eq query, query.toLongOrNull()?.let { SteamwarUserTable.discordId eq it }) }
.firstOrNull()
?.let { return@transaction it }
}
fun joinedOr(vararg expressions: Expression<Boolean>?): Op<Boolean> =
expressions.filterNotNull().reduce { acc, expression -> acc or expression } as Op<Boolean>
fun <T> JdbcTransaction.execute(sql: String, transform: (ResultSet) -> T): List<T> {
val result = mutableListOf<T>()
exec(sql) { rs ->
while (rs.next()) {
result += transform(rs)
}
}
return result
}
fun <T> JdbcTransaction.executeSingle(sql: String, transform: (ResultSet) -> T): T? {
return execute(sql) { rs ->
if (!rs.next()) {
return@execute null
}
transform(rs)
}.single()
}
fun useDb(statement: JdbcTransaction.() -> Unit) {
de.steamwar.db.Database.ensureConnected()
transaction(de.steamwar.db.Database.db, statement)
}