diff options
Diffstat (limited to 'src/main/kotlin/io/dico/parcels2/storage/migration')
3 files changed, 43 insertions, 34 deletions
diff --git a/src/main/kotlin/io/dico/parcels2/storage/migration/Migration.kt b/src/main/kotlin/io/dico/parcels2/storage/migration/Migration.kt index c8bc93c..0db669a 100644 --- a/src/main/kotlin/io/dico/parcels2/storage/migration/Migration.kt +++ b/src/main/kotlin/io/dico/parcels2/storage/migration/Migration.kt @@ -1,8 +1,9 @@ package io.dico.parcels2.storage.migration import io.dico.parcels2.storage.Storage +import kotlinx.coroutines.experimental.Job interface Migration { - fun migrateTo(storage: Storage) + fun migrateTo(storage: Storage): Job } diff --git a/src/main/kotlin/io/dico/parcels2/storage/migration/plotme/PlotmeMigration.kt b/src/main/kotlin/io/dico/parcels2/storage/migration/plotme/PlotmeMigration.kt index e5b7d9d..1f6e49c 100644 --- a/src/main/kotlin/io/dico/parcels2/storage/migration/plotme/PlotmeMigration.kt +++ b/src/main/kotlin/io/dico/parcels2/storage/migration/plotme/PlotmeMigration.kt @@ -1,50 +1,50 @@ +@file:Suppress("RedundantSuspendModifier", "DEPRECATION") + package io.dico.parcels2.storage.migration.plotme import com.zaxxer.hikari.HikariDataSource import io.dico.parcels2.* +import io.dico.parcels2.options.PlotmeMigrationOptions import io.dico.parcels2.storage.Storage import io.dico.parcels2.storage.migration.Migration import io.dico.parcels2.util.Vec2i import io.dico.parcels2.util.isValid import io.dico.parcels2.util.toUUID import io.dico.parcels2.util.uuid -import kotlinx.coroutines.experimental.asCoroutineDispatcher -import kotlinx.coroutines.experimental.launch +import kotlinx.coroutines.experimental.* import org.bukkit.Bukkit import org.jetbrains.exposed.sql.* import org.slf4j.LoggerFactory import java.io.ByteArrayOutputStream import java.sql.Blob import java.util.UUID -import java.util.concurrent.Executors +import java.util.concurrent.ConcurrentHashMap import javax.sql.DataSource +import kotlin.coroutines.experimental.coroutineContext -class PlotmeMigration(val parcelProvider: ParcelProvider, - val worldMapper: Map<String, String>, - val dataSourceFactory: () -> DataSource) : Migration { +class PlotmeMigration(val options: PlotmeMigrationOptions) : Migration { private var dataSource: DataSource? = null private var database: Database? = null private var isShutdown: Boolean = false - private val dispatcher = Executors.newSingleThreadExecutor { Thread(it, "PlotMe Migration Thread") }.asCoroutineDispatcher() private val mlogger = LoggerFactory.getLogger("PlotMe Migrator") private fun <T> transaction(statement: Transaction.() -> T) = org.jetbrains.exposed.sql.transactions.transaction(database!!, statement) - override fun migrateTo(storage: Storage) { - launch(context = dispatcher) { + override fun migrateTo(storage: Storage): Job { + return launch(context = storage.asyncDispatcher) { init() - doWork(storage) + transaction { launch(context = Unconfined, start = CoroutineStart.UNDISPATCHED) { doWork(storage) } } shutdown() } } - fun init() { + suspend fun init() { if (isShutdown) throw IllegalStateException() - dataSource = dataSourceFactory() + dataSource = options.storage.getDataSourceFactory()!!() database = Database.connect(dataSource!!) } - fun shutdown() { + suspend fun shutdown() { if (isShutdown) throw IllegalStateException() dataSource?.let { (it as? HikariDataSource)?.close() @@ -53,22 +53,23 @@ class PlotmeMigration(val parcelProvider: ParcelProvider, isShutdown = true } - val parcelsCache = hashMapOf<String, MutableMap<Vec2i, ParcelData>>() + private val parcelsCache = hashMapOf<String, MutableMap<Vec2i, ParcelData>>() private fun getMap(worldName: String): MutableMap<Vec2i, ParcelData>? { - val mapped = worldMapper[worldName] ?: return null + val mapped = options.worldsFromTo[worldName] ?: return null return parcelsCache.computeIfAbsent(mapped) { mutableMapOf() } } private fun getData(worldName: String, position: Vec2i): ParcelData? { - return getMap(worldName)?.computeIfAbsent(position) { ParcelDataHolder() } + return getMap(worldName)?.computeIfAbsent(position) { ParcelDataHolder(addedMap = ConcurrentHashMap()) } } - fun doWork(target: Storage): Unit = transaction { + suspend fun doWork(target: Storage): Unit { if (!PlotmePlotsT.exists()) { mlogger.warn("Plotme tables don't appear to exist. Exiting.") - return@transaction + return } + parcelsCache.clear() iterPlotmeTable(PlotmePlotsT) { data, row -> @@ -76,22 +77,29 @@ class PlotmeMigration(val parcelProvider: ParcelProvider, data.owner = ParcelOwner(row[owner_uuid]?.toUUID(), row[owner_name]) } - iterPlotmeTable(PlotmeAllowedT) { data, row -> - val uuid = row[player_uuid]?.toUUID() - ?: Bukkit.getOfflinePlayer(row[player_name]).takeIf { it.isValid }?.uuid - ?: return@iterPlotmeTable + launch(context = target.asyncDispatcher) { + iterPlotmeTable(PlotmeAllowedT) { data, row -> + val uuid = row[player_uuid]?.toUUID() + ?: Bukkit.getOfflinePlayer(row[player_name]).takeIf { it.isValid }?.uuid + ?: return@iterPlotmeTable - data.setAddedStatus(uuid, AddedStatus.ALLOWED) + data.setAddedStatus(uuid, AddedStatus.ALLOWED) + } } - iterPlotmeTable(PlotmeDeniedT) { data, row -> - val uuid = row[PlotmeAllowedT.player_uuid]?.toUUID() - ?: Bukkit.getOfflinePlayer(row[PlotmeAllowedT.player_name]).takeIf { it.isValid }?.uuid - ?: return@iterPlotmeTable + launch(context = target.asyncDispatcher) { + iterPlotmeTable(PlotmeDeniedT) { data, row -> + val uuid = row[player_uuid]?.toUUID() + ?: Bukkit.getOfflinePlayer(row[player_name]).takeIf { it.isValid }?.uuid + ?: return@iterPlotmeTable - data.setAddedStatus(uuid, AddedStatus.BANNED) + data.setAddedStatus(uuid, AddedStatus.BANNED) + } } + println(coroutineContext[Job]!!.children) + coroutineContext[Job]!!.joinChildren() + for ((worldName, map) in parcelsCache) { val world = ParcelWorldId(worldName) for ((pos, data) in map) { diff --git a/src/main/kotlin/io/dico/parcels2/storage/migration/plotme/PlotmeTables.kt b/src/main/kotlin/io/dico/parcels2/storage/migration/plotme/PlotmeTables.kt index 3d07955..8564ad3 100644 --- a/src/main/kotlin/io/dico/parcels2/storage/migration/plotme/PlotmeTables.kt +++ b/src/main/kotlin/io/dico/parcels2/storage/migration/plotme/PlotmeTables.kt @@ -7,9 +7,9 @@ const val uppercase: Boolean = false fun String.toCorrectCase() = if (uppercase) this else toLowerCase() sealed class PlotmeTable(name: String) : Table(name) { - val px = PlotmePlotsT.integer("idX").primaryKey() - val pz = PlotmePlotsT.integer("idZ").primaryKey() - val world_name = PlotmePlotsT.varchar("world", 32).primaryKey() + val px = integer("idX").primaryKey() + val pz = integer("idZ").primaryKey() + val world_name = varchar("world", 32).primaryKey() } object PlotmePlotsT : PlotmeTable("plotmePlots".toCorrectCase()) { @@ -18,8 +18,8 @@ object PlotmePlotsT : PlotmeTable("plotmePlots".toCorrectCase()) { } sealed class PlotmePlotPlayerMap(name: String) : PlotmeTable(name) { - val player_name = PlotmePlotsT.varchar("player", 32) - val player_uuid = PlotmePlotsT.blob("playerid").nullable() + val player_name = varchar("player", 32) + val player_uuid = blob("playerid").nullable() } object PlotmeAllowedT : PlotmePlotPlayerMap("plotmeAllowed".toCorrectCase()) |