Fixed several bugs with the new data system
This commit is contained in:
@@ -9,6 +9,8 @@ import java.util.UUID;
|
|||||||
/**
|
/**
|
||||||
* Handles data read/write for a {@link com.willfp.eco.core.data.keys.PersistentDataKeyType} for a specific
|
* Handles data read/write for a {@link com.willfp.eco.core.data.keys.PersistentDataKeyType} for a specific
|
||||||
* data handler.
|
* data handler.
|
||||||
|
*
|
||||||
|
* @param <T> The type of data.
|
||||||
*/
|
*/
|
||||||
public abstract class DataTypeSerializer<T> {
|
public abstract class DataTypeSerializer<T> {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package com.willfp.eco.core.data.handlers;
|
package com.willfp.eco.core.data.handlers;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco;
|
||||||
import com.willfp.eco.core.data.keys.PersistentDataKey;
|
import com.willfp.eco.core.data.keys.PersistentDataKey;
|
||||||
import com.willfp.eco.core.registry.Registrable;
|
import com.willfp.eco.core.registry.Registrable;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -125,7 +127,10 @@ public abstract class PersistentDataHandler implements Registrable {
|
|||||||
|
|
||||||
for (PersistentDataKey<?> key : keys) {
|
for (PersistentDataKey<?> key : keys) {
|
||||||
Object value = read(uuid, key);
|
Object value = read(uuid, key);
|
||||||
data.put(key, value);
|
|
||||||
|
if (value != null) {
|
||||||
|
data.put(key, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
profiles.add(new SerializedProfile(uuid, data));
|
profiles.add(new SerializedProfile(uuid, data));
|
||||||
@@ -151,13 +156,20 @@ public abstract class PersistentDataHandler implements Registrable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Await outstanding writes.
|
* Save and shutdown the handler.
|
||||||
|
*
|
||||||
|
* @throws InterruptedException If the writes could not be awaited.
|
||||||
*/
|
*/
|
||||||
public final void awaitOutstandingWrites() throws InterruptedException {
|
public final void shutdown() throws InterruptedException {
|
||||||
boolean success = executor.awaitTermination(2, TimeUnit.MINUTES);
|
doSave();
|
||||||
|
|
||||||
if (!success) {
|
if (executor.isShutdown()) {
|
||||||
throw new InterruptedException("Failed to await outstanding writes");
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
executor.shutdown();
|
||||||
|
while (!executor.awaitTermination(2, TimeUnit.MINUTES)) {
|
||||||
|
// Wait
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,18 +178,4 @@ public abstract class PersistentDataHandler implements Registrable {
|
|||||||
public final String getID() {
|
public final String getID() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(@NotNull final Object obj) {
|
|
||||||
if (!(obj instanceof PersistentDataHandler other)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return other.getClass().equals(this.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return this.getClass().hashCode();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ import org.bukkit.inventory.ItemStack
|
|||||||
|
|
||||||
abstract class EcoSpigotPlugin : EcoPlugin() {
|
abstract class EcoSpigotPlugin : EcoPlugin() {
|
||||||
abstract val dataYml: DataYml
|
abstract val dataYml: DataYml
|
||||||
protected abstract val profileHandler: ProfileHandler
|
abstract val profileHandler: ProfileHandler
|
||||||
protected var bukkitAudiences: BukkitAudiences? = null
|
protected var bukkitAudiences: BukkitAudiences? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ object PersistentDataHandlers: Registry<PersistentDataHandlerFactory>() {
|
|||||||
|
|
||||||
register(object : PersistentDataHandlerFactory("mysql") {
|
register(object : PersistentDataHandlerFactory("mysql") {
|
||||||
override fun create(plugin: EcoSpigotPlugin) =
|
override fun create(plugin: EcoSpigotPlugin) =
|
||||||
MySQLPersistentDataHandler(plugin, plugin.configYml.getSubsection("mysql"))
|
MySQLPersistentDataHandler(plugin.configYml.getSubsection("mysql"))
|
||||||
})
|
})
|
||||||
|
|
||||||
register(object : PersistentDataHandlerFactory("mongo") {
|
register(object : PersistentDataHandlerFactory("mongo") {
|
||||||
override fun create(plugin: EcoSpigotPlugin) =
|
override fun create(plugin: EcoSpigotPlugin) =
|
||||||
MongoPersistentDataHandler(plugin, plugin.configYml.getSubsection("mongodb"))
|
MongoPersistentDataHandler(plugin.configYml.getSubsection("mongodb"))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import java.math.BigDecimal
|
|||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
class LegacyMySQLPersistentDataHandler(
|
class LegacyMySQLPersistentDataHandler(
|
||||||
plugin: EcoSpigotPlugin,
|
|
||||||
config: Config
|
config: Config
|
||||||
) : PersistentDataHandler("legacy_mysql") {
|
) : PersistentDataHandler("legacy_mysql") {
|
||||||
private val dataSource = HikariDataSource(HikariConfig().apply {
|
private val dataSource = HikariDataSource(HikariConfig().apply {
|
||||||
@@ -101,7 +100,7 @@ class LegacyMySQLPersistentDataHandler(
|
|||||||
|
|
||||||
object Factory: PersistentDataHandlerFactory("legacy_mysql") {
|
object Factory: PersistentDataHandlerFactory("legacy_mysql") {
|
||||||
override fun create(plugin: EcoSpigotPlugin): PersistentDataHandler {
|
override fun create(plugin: EcoSpigotPlugin): PersistentDataHandler {
|
||||||
return LegacyMySQLPersistentDataHandler(plugin, plugin.configYml.getSubsection("mysql"))
|
return LegacyMySQLPersistentDataHandler(plugin.configYml.getSubsection("mysql"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import java.math.BigDecimal
|
|||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
class MongoPersistentDataHandler(
|
class MongoPersistentDataHandler(
|
||||||
plugin: EcoSpigotPlugin,
|
|
||||||
config: Config
|
config: Config
|
||||||
) : PersistentDataHandler("mongo") {
|
) : PersistentDataHandler("mongo") {
|
||||||
private val client = MongoClient.create(config.getString("url"))
|
private val client = MongoClient.create(config.getString("url"))
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import com.willfp.eco.core.data.handlers.DataTypeSerializer
|
|||||||
import com.willfp.eco.core.data.handlers.PersistentDataHandler
|
import com.willfp.eco.core.data.handlers.PersistentDataHandler
|
||||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||||
import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
||||||
import com.willfp.eco.internal.spigot.EcoSpigotPlugin
|
|
||||||
import com.zaxxer.hikari.HikariConfig
|
import com.zaxxer.hikari.HikariConfig
|
||||||
import com.zaxxer.hikari.HikariDataSource
|
import com.zaxxer.hikari.HikariDataSource
|
||||||
import org.jetbrains.exposed.sql.Column
|
import org.jetbrains.exposed.sql.Column
|
||||||
@@ -25,7 +24,6 @@ import java.math.BigDecimal
|
|||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
class MySQLPersistentDataHandler(
|
class MySQLPersistentDataHandler(
|
||||||
plugin: EcoSpigotPlugin,
|
|
||||||
config: Config
|
config: Config
|
||||||
) : PersistentDataHandler("mysql") {
|
) : PersistentDataHandler("mysql") {
|
||||||
private val dataSource = HikariDataSource(HikariConfig().apply {
|
private val dataSource = HikariDataSource(HikariConfig().apply {
|
||||||
@@ -48,32 +46,32 @@ class MySQLPersistentDataHandler(
|
|||||||
override val table = object : KeyTable<String>("string") {
|
override val table = object : KeyTable<String>("string") {
|
||||||
override val value = varchar("value", 128)
|
override val value = varchar("value", 128)
|
||||||
}
|
}
|
||||||
})
|
}.createTable())
|
||||||
|
|
||||||
PersistentDataKeyType.BOOLEAN.registerSerializer(this, object : DirectStoreSerializer<Boolean>() {
|
PersistentDataKeyType.BOOLEAN.registerSerializer(this, object : DirectStoreSerializer<Boolean>() {
|
||||||
override val table = object : KeyTable<Boolean>("boolean") {
|
override val table = object : KeyTable<Boolean>("boolean") {
|
||||||
override val value = bool("value")
|
override val value = bool("value")
|
||||||
}
|
}
|
||||||
})
|
}.createTable())
|
||||||
|
|
||||||
PersistentDataKeyType.INT.registerSerializer(this, object : DirectStoreSerializer<Int>() {
|
PersistentDataKeyType.INT.registerSerializer(this, object : DirectStoreSerializer<Int>() {
|
||||||
override val table = object : KeyTable<Int>("int") {
|
override val table = object : KeyTable<Int>("int") {
|
||||||
override val value = integer("value")
|
override val value = integer("value")
|
||||||
}
|
}
|
||||||
})
|
}.createTable())
|
||||||
|
|
||||||
PersistentDataKeyType.DOUBLE.registerSerializer(this, object : DirectStoreSerializer<Double>() {
|
PersistentDataKeyType.DOUBLE.registerSerializer(this, object : DirectStoreSerializer<Double>() {
|
||||||
override val table = object : KeyTable<Double>("double") {
|
override val table = object : KeyTable<Double>("double") {
|
||||||
override val value = double("value")
|
override val value = double("value")
|
||||||
}
|
}
|
||||||
})
|
}.createTable())
|
||||||
|
|
||||||
PersistentDataKeyType.BIG_DECIMAL.registerSerializer(this, object : DirectStoreSerializer<BigDecimal>() {
|
PersistentDataKeyType.BIG_DECIMAL.registerSerializer(this, object : DirectStoreSerializer<BigDecimal>() {
|
||||||
override val table = object : KeyTable<BigDecimal>("big_decimal") {
|
override val table = object : KeyTable<BigDecimal>("big_decimal") {
|
||||||
// 34 digits of precision, 4 digits of scale
|
// 34 digits of precision, 4 digits of scale
|
||||||
override val value = decimal("value", 34, 4)
|
override val value = decimal("value", 34, 4)
|
||||||
}
|
}
|
||||||
})
|
}.createTable())
|
||||||
|
|
||||||
PersistentDataKeyType.CONFIG.registerSerializer(this, object : SingleValueSerializer<Config, String>() {
|
PersistentDataKeyType.CONFIG.registerSerializer(this, object : SingleValueSerializer<Config, String>() {
|
||||||
override val table = object : KeyTable<String>("config") {
|
override val table = object : KeyTable<String>("config") {
|
||||||
@@ -92,13 +90,13 @@ class MySQLPersistentDataHandler(
|
|||||||
Configs.fromMap(value.toMap(), ConfigType.JSON).toPlaintext()
|
Configs.fromMap(value.toMap(), ConfigType.JSON).toPlaintext()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}.createTable())
|
||||||
|
|
||||||
PersistentDataKeyType.STRING_LIST.registerSerializer(this, object : MultiValueSerializer<String>() {
|
PersistentDataKeyType.STRING_LIST.registerSerializer(this, object : MultiValueSerializer<String>() {
|
||||||
override val table = object : ListKeyTable<String>("string_list") {
|
override val table = object : ListKeyTable<String>("string_list") {
|
||||||
override val value = varchar("value", 128)
|
override val value = varchar("value", 128)
|
||||||
}
|
}
|
||||||
})
|
}.createTable())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSavedUUIDs(): Set<UUID> {
|
override fun getSavedUUIDs(): Set<UUID> {
|
||||||
@@ -115,22 +113,24 @@ class MySQLPersistentDataHandler(
|
|||||||
private abstract inner class MySQLSerializer<T : Any> : DataTypeSerializer<T>() {
|
private abstract inner class MySQLSerializer<T : Any> : DataTypeSerializer<T>() {
|
||||||
protected abstract val table: ProfileTable
|
protected abstract val table: ProfileTable
|
||||||
|
|
||||||
init {
|
|
||||||
transaction(database) {
|
|
||||||
SchemaUtils.create(table)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getSavedUUIDs(): Set<UUID> {
|
fun getSavedUUIDs(): Set<UUID> {
|
||||||
return transaction(database) {
|
return transaction(database) {
|
||||||
table.selectAll().map { it[table.uuid] }.toSet()
|
table.selectAll().map { it[table.uuid] }.toSet()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun createTable(): MySQLSerializer<T> {
|
||||||
|
transaction(database) {
|
||||||
|
SchemaUtils.create(table)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// T is the key type
|
// T is the key type
|
||||||
// S is the stored value type
|
// S is the stored value type
|
||||||
private abstract inner class SingleValueSerializer<T : Any, S: Any> : MySQLSerializer<T>() {
|
private abstract inner class SingleValueSerializer<T : Any, S : Any> : MySQLSerializer<T>() {
|
||||||
abstract override val table: KeyTable<S>
|
abstract override val table: KeyTable<S>
|
||||||
|
|
||||||
abstract fun convertToStored(value: T): S
|
abstract fun convertToStored(value: T): S
|
||||||
@@ -148,17 +148,21 @@ class MySQLPersistentDataHandler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun writeAsync(uuid: UUID, key: PersistentDataKey<T>, value: T) {
|
override fun writeAsync(uuid: UUID, key: PersistentDataKey<T>, value: T) {
|
||||||
transaction(database) {
|
withRetries {
|
||||||
table.insert {
|
transaction(database) {
|
||||||
it[table.uuid] = uuid
|
table.deleteWhere { (table.uuid eq uuid) and (table.key eq key.key.toString()) }
|
||||||
it[table.key] = key.key.toString()
|
|
||||||
it[table.value] = convertToStored(value)
|
table.insert {
|
||||||
|
it[table.uuid] = uuid
|
||||||
|
it[table.key] = key.key.toString()
|
||||||
|
it[table.value] = convertToStored(value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private abstract inner class DirectStoreSerializer<T: Any> : SingleValueSerializer<T, T>() {
|
private abstract inner class DirectStoreSerializer<T : Any> : SingleValueSerializer<T, T>() {
|
||||||
override fun convertToStored(value: T): T {
|
override fun convertToStored(value: T): T {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
@@ -168,7 +172,7 @@ class MySQLPersistentDataHandler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private abstract inner class MultiValueSerializer<T: Any> : MySQLSerializer<List<T>>() {
|
private abstract inner class MultiValueSerializer<T : Any> : MySQLSerializer<List<T>>() {
|
||||||
abstract override val table: ListKeyTable<T>
|
abstract override val table: ListKeyTable<T>
|
||||||
|
|
||||||
override fun readAsync(uuid: UUID, key: PersistentDataKey<List<T>>): List<T>? {
|
override fun readAsync(uuid: UUID, key: PersistentDataKey<List<T>>): List<T>? {
|
||||||
@@ -182,15 +186,17 @@ class MySQLPersistentDataHandler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun writeAsync(uuid: UUID, key: PersistentDataKey<List<T>>, value: List<T>) {
|
override fun writeAsync(uuid: UUID, key: PersistentDataKey<List<T>>, value: List<T>) {
|
||||||
transaction(database) {
|
withRetries {
|
||||||
table.deleteWhere { (table.uuid eq uuid) and (table.key eq key.key.toString()) }
|
transaction(database) {
|
||||||
|
table.deleteWhere { (table.uuid eq uuid) and (table.key eq key.key.toString()) }
|
||||||
|
|
||||||
value.forEachIndexed { index, t ->
|
value.forEachIndexed { index, t ->
|
||||||
table.insert {
|
table.insert {
|
||||||
it[table.uuid] = uuid
|
it[table.uuid] = uuid
|
||||||
it[table.key] = key.key.toString()
|
it[table.key] = key.key.toString()
|
||||||
it[table.index] = index
|
it[table.index] = index
|
||||||
it[table.value] = t
|
it[table.value] = t
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -208,7 +214,7 @@ class MySQLPersistentDataHandler(
|
|||||||
override val primaryKey = PrimaryKey(uuid, key)
|
override val primaryKey = PrimaryKey(uuid, key)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
uniqueIndex()
|
uniqueIndex(uuid, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,7 +226,21 @@ class MySQLPersistentDataHandler(
|
|||||||
override val primaryKey = PrimaryKey(uuid, key, index)
|
override val primaryKey = PrimaryKey(uuid, key, index)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
uniqueIndex()
|
uniqueIndex(uuid, key, index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline fun <T> withRetries(action: () -> T): T {
|
||||||
|
var retries = 0
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
return action()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
if (retries >= 3) {
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
retries++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.willfp.eco.internal.spigot.data.KeyRegistry
|
|||||||
import com.willfp.eco.internal.spigot.data.handlers.PersistentDataHandlerFactory
|
import com.willfp.eco.internal.spigot.data.handlers.PersistentDataHandlerFactory
|
||||||
import com.willfp.eco.internal.spigot.data.handlers.PersistentDataHandlers
|
import com.willfp.eco.internal.spigot.data.handlers.PersistentDataHandlers
|
||||||
import com.willfp.eco.internal.spigot.data.handlers.impl.LegacyMySQLPersistentDataHandler
|
import com.willfp.eco.internal.spigot.data.handlers.impl.LegacyMySQLPersistentDataHandler
|
||||||
|
import com.willfp.eco.internal.spigot.data.handlers.impl.MySQLPersistentDataHandler
|
||||||
import com.willfp.eco.internal.spigot.data.handlers.impl.YamlPersistentDataHandler
|
import com.willfp.eco.internal.spigot.data.handlers.impl.YamlPersistentDataHandler
|
||||||
import com.willfp.eco.internal.spigot.data.profiles.impl.EcoPlayerProfile
|
import com.willfp.eco.internal.spigot.data.profiles.impl.EcoPlayerProfile
|
||||||
import com.willfp.eco.internal.spigot.data.profiles.impl.EcoProfile
|
import com.willfp.eco.internal.spigot.data.profiles.impl.EcoProfile
|
||||||
@@ -17,7 +18,7 @@ import java.util.concurrent.ConcurrentHashMap
|
|||||||
class ProfileHandler(
|
class ProfileHandler(
|
||||||
private val plugin: EcoSpigotPlugin
|
private val plugin: EcoSpigotPlugin
|
||||||
) {
|
) {
|
||||||
private val handlerId = plugin.dataYml.getString("data-handler")
|
private val handlerId = plugin.configYml.getString("data-handler")
|
||||||
|
|
||||||
val localHandler = YamlPersistentDataHandler(plugin)
|
val localHandler = YamlPersistentDataHandler(plugin)
|
||||||
val defaultHandler = PersistentDataHandlers[handlerId]
|
val defaultHandler = PersistentDataHandlers[handlerId]
|
||||||
@@ -44,11 +45,8 @@ class ProfileHandler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun save() {
|
fun save() {
|
||||||
localHandler.save()
|
localHandler.shutdown()
|
||||||
defaultHandler.save()
|
defaultHandler.shutdown()
|
||||||
|
|
||||||
localHandler.awaitOutstandingWrites()
|
|
||||||
defaultHandler.awaitOutstandingWrites()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun migrateIfNecessary(): Boolean {
|
fun migrateIfNecessary(): Boolean {
|
||||||
@@ -56,28 +54,25 @@ class ProfileHandler(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// First install
|
||||||
if (!plugin.dataYml.has("previous-handler")) {
|
if (!plugin.dataYml.has("previous-handler")) {
|
||||||
plugin.dataYml.set("previous-handler", defaultHandler.id)
|
plugin.dataYml.set("previous-handler", defaultHandler.id)
|
||||||
|
plugin.dataYml.set("legacy-mysql-migrated", true)
|
||||||
plugin.dataYml.save()
|
plugin.dataYml.save()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defaultHandler.id == "mysql" && !plugin.dataYml.getBool("legacy-mysql-migrated")) {
|
val previousHandlerId = plugin.dataYml.getString("previous-handler").lowercase()
|
||||||
plugin.logger.info("eco has detected a legacy MySQL database. Migrating to new MySQL database...")
|
if (previousHandlerId != defaultHandler.id) {
|
||||||
scheduleMigration(LegacyMySQLPersistentDataHandler.Factory)
|
val fromFactory = PersistentDataHandlers[previousHandlerId] ?: return false
|
||||||
|
scheduleMigration(fromFactory)
|
||||||
plugin.dataYml.set("legacy-mysql-migrated", true)
|
|
||||||
plugin.dataYml.save()
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (defaultHandler is MySQLPersistentDataHandler && !plugin.dataYml.getBool("legacy-mysql-migrated")) {
|
||||||
val previousHandlerId = plugin.dataYml.getString("previous-handler")
|
plugin.logger.info("eco has detected a legacy MySQL database. Migrating to new MySQL database...")
|
||||||
if (previousHandlerId != defaultHandler.id) {
|
scheduleMigration(LegacyMySQLPersistentDataHandler.Factory)
|
||||||
val fromFactory = PersistentDataHandlers[previousHandlerId] ?: return false
|
|
||||||
|
|
||||||
scheduleMigration(fromFactory)
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -91,12 +86,15 @@ class ProfileHandler(
|
|||||||
// Run after 5 ticks to allow plugins to load their data keys
|
// Run after 5 ticks to allow plugins to load their data keys
|
||||||
plugin.scheduler.runLater(5) {
|
plugin.scheduler.runLater(5) {
|
||||||
doMigrate(fromFactory)
|
doMigrate(fromFactory)
|
||||||
|
|
||||||
|
plugin.dataYml.set("legacy-mysql-migrated", true)
|
||||||
|
plugin.dataYml.save()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doMigrate(fromFactory: PersistentDataHandlerFactory) {
|
private fun doMigrate(fromFactory: PersistentDataHandlerFactory) {
|
||||||
plugin.logger.info("eco has detected a change in data handler")
|
plugin.logger.info("eco has detected a change in data handler")
|
||||||
plugin.logger.info("${fromFactory.id} --> $handlerId")
|
plugin.logger.info("${fromFactory.id} --> ${defaultHandler.id}")
|
||||||
plugin.logger.info("This will take a while! Players will not be able to join during this time.")
|
plugin.logger.info("This will take a while! Players will not be able to join during this time.")
|
||||||
|
|
||||||
val fromHandler = fromFactory.create(plugin)
|
val fromHandler = fromFactory.create(plugin)
|
||||||
@@ -114,7 +112,7 @@ class ProfileHandler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
plugin.logger.info("Profile writes submitted! Waiting for completion...")
|
plugin.logger.info("Profile writes submitted! Waiting for completion...")
|
||||||
toHandler.awaitOutstandingWrites()
|
toHandler.shutdown()
|
||||||
|
|
||||||
plugin.logger.info("Updating previous handler...")
|
plugin.logger.info("Updating previous handler...")
|
||||||
plugin.dataYml.set("previous-handler", handlerId)
|
plugin.dataYml.set("previous-handler", handlerId)
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
# How player/server data is saved:
|
# How player/server data is saved:
|
||||||
# yaml - Stored in data.yml: Good option for single-node servers (i.e. no BungeeCord/Velocity)
|
# yaml - Stored in data.yml: Good option for single-node servers (i.e. no BungeeCord/Velocity)
|
||||||
# mongo - If you're running on a network (Bungee/Velocity), you should use MongoDB if you can.
|
# mysql - Standard database, great option for multi-node servers (i.e. BungeeCord/Velocity)
|
||||||
# mysql - The alternative to MongoDB. Because of how eco data works, MongoDB is the best option; but use this if you can't.
|
# mongo - Alternative database, may suit some servers better
|
||||||
data-handler: yaml
|
data-handler: yaml
|
||||||
|
|
||||||
# If data should be migrated automatically when changing data handler.
|
# If data should be migrated automatically when changing data handler.
|
||||||
|
|||||||
Reference in New Issue
Block a user