Merge pull request #35 from SKBotNL/master
Database migrations and "total" field in PlayerShards
This commit was merged in pull request #35.
This commit is contained in:
8 files changed
+97
-88
No files matched your search
@@ -55,9 +55,16 @@ repositories {
|
||||
dependencies {
|
||||
compileOnly("org.purpurmc.purpur:purpur-api:1.19.4-R0.1-SNAPSHOT") // Declare Purpur API version to be packaged.
|
||||
compileOnly("net.luckperms:api:5.5") // Import the LuckPerms API.
|
||||
|
||||
implementation("io.lettuce:lettuce-core:7.2.0.RELEASE") // Import the Lettuce API for keydb.
|
||||
|
||||
implementation("org.flywaydb:flyway-core:12.3.0")
|
||||
implementation("org.flywaydb:flyway-database-postgresql:12.3.0")
|
||||
implementation("org.postgresql:postgresql:42.7.9")
|
||||
implementation("com.github.jasync-sql:jasync-postgresql:2.2.4") // Import the jasync Postgres API.
|
||||
|
||||
implementation("it.unimi.dsi:fastutil-core:8.5.16")
|
||||
|
||||
implementation("org.jetbrains.kotlin:kotlin-stdlib") // Import the Kotlin standard library.
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")
|
||||
implementation("org.slf4j:slf4j-api:2.0.17") // Bundle a relocated SLF4J API for shaded dependencies.
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
package net.trueog.diamondbankog
|
||||
|
||||
import java.sql.SQLException
|
||||
import java.util.*
|
||||
import net.trueog.diamondbankog.PostgreSQL.PlayerShards
|
||||
import net.trueog.diamondbankog.PostgreSQL.ShardType
|
||||
|
||||
interface BalanceManager {
|
||||
@Throws(SQLException::class, ClassNotFoundException::class) fun init()
|
||||
|
||||
suspend fun setPlayerShards(uuid: UUID, shards: Long, type: ShardType): Result<Unit>
|
||||
|
||||
suspend fun addToBankShards(uuid: UUID, shards: Long): Result<Unit>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package net.trueog.diamondbankog
|
||||
|
||||
interface BalanceManagerFactory {
|
||||
fun create(): BalanceManager?
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package net.trueog.diamondbankog
|
||||
|
||||
import java.sql.SQLException
|
||||
import java.util.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
@@ -11,14 +10,17 @@ import net.trueog.diamondbankog.ErrorHandler.handleError
|
||||
import net.trueog.diamondbankog.PostgreSQL.PlayerShards
|
||||
import net.trueog.diamondbankog.PostgreSQL.ShardType
|
||||
|
||||
internal class CachingBalanceManager : BalanceManager {
|
||||
internal class CachingBalanceManager private constructor() : BalanceManager {
|
||||
val cache = Cache()
|
||||
val postgreSQL = PostgreSQL()
|
||||
lateinit var postgreSQL: PostgreSQL
|
||||
val beingModified = ConcurrentHashMap<Pair<UUID, ShardType>, AtomicInteger>()
|
||||
|
||||
@Throws(SQLException::class, ClassNotFoundException::class)
|
||||
override fun init() {
|
||||
postgreSQL.initDB()
|
||||
companion object : BalanceManagerFactory {
|
||||
override fun create(): BalanceManager? {
|
||||
val cachingBalanceManager = CachingBalanceManager()
|
||||
cachingBalanceManager.postgreSQL = PostgreSQL.create() ?: return null
|
||||
return cachingBalanceManager
|
||||
}
|
||||
}
|
||||
|
||||
private fun increment(uuid: UUID, type: ShardType) {
|
||||
|
||||
@@ -21,7 +21,7 @@ internal open class DiamondBankOG : JavaPlugin() {
|
||||
lateinit var plugin: DiamondBankOG
|
||||
lateinit var config: YamlConfig
|
||||
lateinit var eventManager: EventManager
|
||||
lateinit var balanceManager: CachingBalanceManager
|
||||
lateinit var balanceManager: BalanceManager
|
||||
lateinit var redis: Redis
|
||||
lateinit var luckPerms: LuckPerms
|
||||
|
||||
@@ -59,14 +59,12 @@ internal open class DiamondBankOG : JavaPlugin() {
|
||||
|
||||
eventManager = EventManager()
|
||||
|
||||
balanceManager = CachingBalanceManager()
|
||||
try {
|
||||
balanceManager.init()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
Bukkit.getPluginManager().disablePlugin(this)
|
||||
return
|
||||
}
|
||||
balanceManager =
|
||||
CachingBalanceManager.create()
|
||||
?: run {
|
||||
Bukkit.getPluginManager().disablePlugin(this)
|
||||
return
|
||||
}
|
||||
|
||||
redis = Redis()
|
||||
if (redis.testConnection()) {
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.github.jasync.sql.db.asSuspending
|
||||
import com.github.jasync.sql.db.pool.ConnectionPool
|
||||
import com.github.jasync.sql.db.postgresql.PostgreSQLConnection
|
||||
import com.github.jasync.sql.db.postgresql.PostgreSQLConnectionBuilder
|
||||
import java.sql.SQLException
|
||||
import java.util.*
|
||||
import kotlinx.coroutines.future.await
|
||||
import net.trueog.diamondbankog.DiamondBankException.*
|
||||
@@ -12,8 +11,10 @@ import net.trueog.diamondbankog.DiamondBankOG.Companion.balanceManager
|
||||
import net.trueog.diamondbankog.DiamondBankOG.Companion.config
|
||||
import net.trueog.diamondbankog.DiamondBankOG.Companion.economyDisabled
|
||||
import net.trueog.diamondbankog.DiamondBankOG.Companion.plugin
|
||||
import org.flywaydb.core.Flyway
|
||||
import org.postgresql.ds.PGSimpleDataSource
|
||||
|
||||
class PostgreSQL {
|
||||
class PostgreSQL private constructor() {
|
||||
lateinit var pool: ConnectionPool<PostgreSQLConnection>
|
||||
|
||||
class NoRowsException : Exception()
|
||||
@@ -25,67 +26,34 @@ class PostgreSQL {
|
||||
TOTAL("bank_shards, inventory_shards, ender_chest_shards"),
|
||||
}
|
||||
|
||||
@Throws(SQLException::class, ClassNotFoundException::class)
|
||||
fun initDB() {
|
||||
try {
|
||||
pool =
|
||||
PostgreSQLConnectionBuilder.createConnectionPool(
|
||||
"${config.postgresUrl}?user=${config.postgresUser}&password=${config.postgresPassword}"
|
||||
)
|
||||
val createTable =
|
||||
pool.sendPreparedStatement(
|
||||
"CREATE TABLE IF NOT EXISTS ${config.postgresTable}(uuid UUID PRIMARY KEY, bank_shards BIGINT DEFAULT 0, inventory_shards BIGINT DEFAULT 0, ender_chest_shards BIGINT DEFAULT 0, total_shards BIGINT GENERATED ALWAYS AS ( COALESCE(bank_shards, 0) + COALESCE(inventory_shards, 0) + COALESCE(ender_chest_shards, 0) ) STORED)"
|
||||
)
|
||||
createTable.join()
|
||||
val createTotalShardsIndex =
|
||||
pool.sendPreparedStatement(
|
||||
"CREATE INDEX IF NOT EXISTS idx_total_shards ON ${config.postgresTable}(total_shards DESC)"
|
||||
)
|
||||
createTotalShardsIndex.join()
|
||||
companion object {
|
||||
fun create(): PostgreSQL? {
|
||||
val postgreSQL = PostgreSQL()
|
||||
|
||||
val createLogTable =
|
||||
pool.sendPreparedStatement(
|
||||
"CREATE TABLE IF NOT EXISTS ${config.postgresLogTable}(id SERIAL PRIMARY KEY, player_uuid UUID NOT NULL, transferred_shards BIGINT NOT NULL, player_to_uuid UUID, transaction_reason TEXT, notes TEXT, timestamp TIMESTAMPTZ DEFAULT NOW())"
|
||||
try {
|
||||
val jdbcUrl = "${config.postgresUrl}?user=${config.postgresUser}&password=${config.postgresPassword}"
|
||||
|
||||
val pg = PGSimpleDataSource()
|
||||
pg.setUrl(jdbcUrl)
|
||||
val flyway = Flyway.configure(DiamondBankOG::class.java.classLoader).dataSource(pg).load()
|
||||
flyway.migrate()
|
||||
|
||||
postgreSQL.pool = PostgreSQLConnectionBuilder.createConnectionPool(jdbcUrl)
|
||||
return postgreSQL
|
||||
} catch (e: Exception) {
|
||||
economyDisabled = true
|
||||
plugin.logger.severe(
|
||||
"ECONOMY DISABLED! Something went wrong while trying to initialise PostgreSQL. Is PostgreSQL running? Are the PostgreSQL config variables correct?"
|
||||
)
|
||||
createLogTable.join()
|
||||
// @formatter:off
|
||||
val createFunction =
|
||||
pool.sendPreparedStatement(
|
||||
"CREATE OR REPLACE FUNCTION fifo_limit_trigger() RETURNS TRIGGER AS $$" +
|
||||
"DECLARE " +
|
||||
"max_rows CONSTANT BIGINT := ${config.postgresLogLimit};" +
|
||||
"BEGIN " +
|
||||
"DELETE FROM ${config.postgresLogTable} " +
|
||||
"WHERE id <= (" +
|
||||
"SELECT id FROM ${config.postgresLogTable} " +
|
||||
"ORDER BY id DESC " +
|
||||
"OFFSET max_rows LIMIT 1" +
|
||||
");" +
|
||||
"RETURN NEW;" +
|
||||
"END;" +
|
||||
"$$ LANGUAGE plpgsql;"
|
||||
)
|
||||
// @formatter:on
|
||||
createFunction.join()
|
||||
val createTrigger =
|
||||
pool.sendPreparedStatement(
|
||||
"CREATE OR REPLACE TRIGGER fifo_limit_trigger\n" +
|
||||
"AFTER INSERT ON ${config.postgresLogTable}\n" +
|
||||
"FOR EACH STATEMENT\n" +
|
||||
"EXECUTE FUNCTION fifo_limit_trigger();"
|
||||
)
|
||||
createTrigger.join()
|
||||
} catch (e: Exception) {
|
||||
economyDisabled = true
|
||||
plugin.logger.severe(
|
||||
"ECONOMY DISABLED! Something went wrong while trying to initialise PostgreSQL. Is PostgreSQL running? Are the PostgreSQL config variables correct?"
|
||||
)
|
||||
e.printStackTrace()
|
||||
return
|
||||
e.printStackTrace()
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class PlayerShards(val bank: Long, val inventory: Long, val enderChest: Long)
|
||||
data class PlayerShards(val bank: Long, val inventory: Long, val enderChest: Long) {
|
||||
val total = bank + inventory + enderChest
|
||||
}
|
||||
|
||||
suspend fun setPlayerShards(uuid: UUID, shards: Long, type: ShardType): Result<Unit> {
|
||||
if (type == ShardType.TOTAL) return Result.failure(InvalidArgumentException())
|
||||
|
||||
@@ -17,23 +17,25 @@ internal class DiamondBankReload : CommandExecutor {
|
||||
YamlConfig.create()
|
||||
?: run {
|
||||
sender.sendMessage(
|
||||
mm.deserialize("<red>Failed to reload the config. Check the console for more information.")
|
||||
mm.deserialize(
|
||||
"${config.prefix}<reset>: <red>Failed to reload the config. Check the console for more information."
|
||||
)
|
||||
)
|
||||
Bukkit.getPluginManager().disablePlugin(plugin)
|
||||
return true
|
||||
}
|
||||
|
||||
balanceManager = CachingBalanceManager()
|
||||
try {
|
||||
balanceManager.init()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
sender.sendMessage(
|
||||
mm.deserialize("<red>Failed to reload the config. Check the console for more information.")
|
||||
)
|
||||
Bukkit.getPluginManager().disablePlugin(plugin)
|
||||
return true
|
||||
}
|
||||
balanceManager =
|
||||
CachingBalanceManager.create()
|
||||
?: run {
|
||||
sender.sendMessage(
|
||||
mm.deserialize(
|
||||
"${config.prefix}<reset>: <red>Failed to reload the config. Check the console for more information."
|
||||
)
|
||||
)
|
||||
Bukkit.getPluginManager().disablePlugin(plugin)
|
||||
return true
|
||||
}
|
||||
|
||||
sender.sendMessage(mm.deserialize("${config.prefix}<reset>: <green>Successfully reloaded the config."))
|
||||
return true
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
CREATE TABLE diamond(
|
||||
uuid UUID PRIMARY KEY, bank_shards BIGINT DEFAULT 0, inventory_shards BIGINT DEFAULT 0, ender_chest_shards BIGINT DEFAULT 0,
|
||||
total_shards BIGINT GENERATED ALWAYS AS ( COALESCE(bank_shards, 0) + COALESCE(inventory_shards, 0) + COALESCE(ender_chest_shards, 0) ) STORED
|
||||
);
|
||||
|
||||
CREATE INDEX idx_total_shards ON diamond(total_shards DESC);
|
||||
|
||||
CREATE TABLE diamond_log(
|
||||
id SERIAL PRIMARY KEY, player_uuid UUID NOT NULL, transferred_shards BIGINT NOT NULL, player_to_uuid UUID,
|
||||
transaction_reason TEXT, notes TEXT, timestamp TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE FUNCTION fifo_limit_trigger() RETURNS TRIGGER AS $$
|
||||
DECLARE
|
||||
max_rows CONSTANT BIGINT := 500;
|
||||
BEGIN
|
||||
DELETE FROM diamond_log
|
||||
WHERE id <= (
|
||||
SELECT id FROM diamond_log
|
||||
ORDER BY id DESC
|
||||
OFFSET max_rows LIMIT 1
|
||||
);
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER fifo_limit_trigger
|
||||
AFTER INSERT ON diamond_log
|
||||
FOR EACH STATEMENT
|
||||
EXECUTE FUNCTION fifo_limit_trigger();
|
||||
Reference in new issue
Block a user