Skip to content

Commit 3a3b7c3

Browse files
committed
support sqlite database
1 parent 667c0f5 commit 3a3b7c3

3 files changed

Lines changed: 53 additions & 22 deletions

File tree

build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ val hikariVersion = "5.0.0"
2020
val mysqlVersion = "8.0.25"
2121
val quartzVersion = "2.3.2"
2222
val miraiSlf4jBridgeVersion = "1.2.0"
23+
val sqliteVersion = "3.36.0.3"
2324

2425
dependencies {
2526
testImplementation(kotlin("test-junit5"))
@@ -32,6 +33,7 @@ dependencies {
3233
implementation("mysql:mysql-connector-java:$mysqlVersion")
3334
implementation("org.quartz-scheduler:quartz:$quartzVersion")
3435
implementation("net.mamoe:mirai-slf4j-bridge:$miraiSlf4jBridgeVersion")
36+
implementation("org.xerial:sqlite-jdbc:$sqliteVersion")
3537
//implementation("org.slf4j:slf4j-simple:1.7.1")
3638
}
3739

src/main/kotlin/me/stageguard/sctimetable/PluginConfig.kt

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,32 @@ object PluginConfig : AutoSavePluginConfig("SG.SCTimeTableBotConfig") {
2424
注意:如果你修改了这个值,在修改之前已经被设置的用户和自己设定值的用户不会受到影响。
2525
""")
2626
val advancedTipTime by value(15)
27-
val database by value<DatabaseConfig>()
27+
@ValueDescription("""
28+
使用的数据库类型,支持 MySQL / MariaDB / SQLite
29+
填 `mysql` 表示使用 MySQL 或 MariaDB。
30+
填 `sqlite` 表示使用 SQLite。
31+
填其他字符为无效选项。
32+
当使用其中一个数据库类型时,另一个数据库配置不会生效。
33+
""")
34+
val database by value("sqlite")
35+
@ValueDescription("""
36+
MySQL / MariaDB 数据库配置。
37+
""")
38+
val mysqlConfig by value(MySQLorMariaDB())
39+
@ValueDescription("""
40+
SQLite 数据库配置。
41+
""")
42+
val sqliteConfig by value(SQLite())
2843
}
2944

3045
@Serializable
31-
data class DatabaseConfig(
46+
data class SQLite(
47+
@ValueDescription("数据库文件名")
48+
val file: String = "sctimetable.db"
49+
)
50+
51+
@Serializable
52+
data class MySQLorMariaDB(
3253
@ValueDescription("""
3354
数据库地址,支持MariaDB和MySQL数据库.
3455
默认值:localhost

src/main/kotlin/me/stageguard/sctimetable/database/Database.kt

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ package me.stageguard.sctimetable.database
1111
import com.zaxxer.hikari.HikariConfig
1212
import com.zaxxer.hikari.HikariDataSource
1313
import kotlinx.coroutines.Dispatchers
14+
import me.stageguard.sctimetable.*
1415
import net.mamoe.mirai.utils.error
1516
import net.mamoe.mirai.utils.info
1617
import net.mamoe.mirai.utils.verbose
@@ -22,10 +23,11 @@ import org.jetbrains.exposed.sql.statements.StatementContext
2223
import org.jetbrains.exposed.sql.statements.expandArgs
2324
import org.jetbrains.exposed.sql.transactions.transaction
2425
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
25-
import me.stageguard.sctimetable.PluginConfig
26-
import me.stageguard.sctimetable.PluginMain
2726
import me.stageguard.sctimetable.database.model.SchoolTimetables
2827
import me.stageguard.sctimetable.database.model.Users
28+
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
29+
import org.jetbrains.exposed.sql.transactions.TransactionManager
30+
import java.sql.Connection
2931

3032
object Database {
3133

@@ -35,7 +37,7 @@ object Database {
3537
}
3638

3739
private lateinit var db : Database
38-
private lateinit var hikariSource: HikariDataSource
40+
private var hikariSource: HikariDataSource? = null
3941
private var connectionStatus: ConnectionStatus = ConnectionStatus.DISCONNECTED
4042

4143
fun <T> query(block: (Transaction) -> T) : T? = if(connectionStatus == ConnectionStatus.DISCONNECTED) {
@@ -49,11 +51,16 @@ object Database {
4951
} else newSuspendedTransaction(context = Dispatchers.IO, db = db) { block(this) }
5052

5153
fun connect() {
52-
db = Database.connect(hikariDataSourceProvider().also {
53-
hikariSource = it
54-
})
54+
db = when (PluginConfig.database) {
55+
"mysql" -> Database.connect(hikariDataSourceProvider(PluginConfig.mysqlConfig))
56+
"sqlite" -> {
57+
TransactionManager.manager.defaultIsolationLevel = Connection.TRANSACTION_SERIALIZABLE
58+
Database.connect("jdbc:sqlite:${PluginMain.dataFolder}/${PluginConfig.sqliteConfig.file}", "org.sqlite.JDBC")
59+
}
60+
else -> throw InvalidDatabaseConfigException("未知的数据库类型或数据库配置未找到:${PluginConfig.database}")
61+
}
5562
connectionStatus = ConnectionStatus.CONNECTED
56-
PluginMain.logger.info { "Database ${PluginConfig.database.table} is connected." }
63+
PluginMain.logger.info { "Database is connected." }
5764
initDatabase()
5865
}
5966

@@ -71,28 +78,29 @@ object Database {
7178

7279
fun close() {
7380
connectionStatus = ConnectionStatus.DISCONNECTED
74-
hikariSource.closeQuietly()
81+
hikariSource?.closeQuietly()
7582
}
7683

77-
private fun hikariDataSourceProvider() : HikariDataSource = HikariDataSource(HikariConfig().apply {
84+
@OptIn(ConsoleExperimentalApi::class)
85+
private fun hikariDataSourceProvider(config: MySQLorMariaDB) : HikariDataSource = HikariDataSource(HikariConfig().apply {
7886
when {
79-
PluginConfig.database.address == "" -> throw InvalidDatabaseConfigException("Database address is not set in config file ${PluginConfig.saveName}.")
80-
PluginConfig.database.table == "" -> {
87+
config.address == "" -> throw InvalidDatabaseConfigException("Database address is not set in config file ${PluginConfig.saveName}.")
88+
config.table == "" -> {
8189
PluginMain.logger.warning { "Database table is not set in config file ${PluginConfig.saveName} and now it will be default value 'sctimetabledb'." }
82-
PluginConfig.database.table = "sctimetabledb"
90+
config.table = "sctimetabledb"
8391
}
84-
PluginConfig.database.user == "" -> throw InvalidDatabaseConfigException("Database user is not set in config file ${PluginConfig.saveName}.")
85-
PluginConfig.database.password == "" -> throw InvalidDatabaseConfigException("Database password is not set in config file ${PluginConfig.saveName}.")
86-
PluginConfig.database.maximumPoolSize == null -> {
92+
config.user == "" -> throw InvalidDatabaseConfigException("Database user is not set in config file ${PluginConfig.saveName}.")
93+
config.password == "" -> throw InvalidDatabaseConfigException("Database password is not set in config file ${PluginConfig.saveName}.")
94+
config.maximumPoolSize == null -> {
8795
PluginMain.logger.warning { "Database maximumPoolSize is not set in config file ${PluginConfig.saveName} and now it will be default value 10." }
88-
PluginConfig.database.maximumPoolSize = 10
96+
config.maximumPoolSize = 10
8997
}
9098
}
91-
jdbcUrl = "jdbc:mysql://${PluginConfig.database.address}/${PluginConfig.database.table}"
99+
jdbcUrl = "jdbc:mysql://${config.address}/${config.table}"
92100
driverClassName = "com.mysql.cj.jdbc.Driver"
93-
username = PluginConfig.database.user
94-
password = PluginConfig.database.password
95-
maximumPoolSize = PluginConfig.database.maximumPoolSize!!
101+
username = config.user
102+
password = config.password
103+
maximumPoolSize = config.maximumPoolSize!!
96104
poolName = "SCTimetableDB Pool"
97105
})
98106

0 commit comments

Comments
 (0)