Minor tweaks, switch to PostgreSQL for debuggigng purposes
This commit is contained in:
115
build.gradle.kts
115
build.gradle.kts
@@ -6,6 +6,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformJvmPlugin
|
||||
import java.io.PrintWriter
|
||||
|
||||
val firstImport = false
|
||||
val stdout = PrintWriter(File("$rootDir/gradle-output.txt"))
|
||||
|
||||
buildscript {
|
||||
@@ -30,8 +31,8 @@ allprojects {
|
||||
}
|
||||
dependencies {
|
||||
val spigotVersion = "1.13-R0.1-SNAPSHOT"
|
||||
compile("org.bukkit:bukkit:$spigotVersion")
|
||||
compile("org.spigotmc:spigot-api:$spigotVersion")
|
||||
compile("org.bukkit:bukkit:$spigotVersion") { isTransitive = false }
|
||||
compile("org.spigotmc:spigot-api:$spigotVersion") { isTransitive = false }
|
||||
|
||||
compile("net.sf.trove4j:trove4j:3.0.3")
|
||||
testCompile("junit:junit:4.12")
|
||||
@@ -80,73 +81,23 @@ dependencies {
|
||||
compile("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion")
|
||||
compile("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonVersion")
|
||||
compile("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:$jacksonVersion")
|
||||
//compile("org.yaml:snakeyaml:1.19")
|
||||
|
||||
compile("org.slf4j:slf4j-api:1.7.25")
|
||||
compile("ch.qos.logback:logback-classic:1.2.3")
|
||||
}
|
||||
|
||||
tasks {
|
||||
val compileKotlin by getting(KotlinCompile::class) {
|
||||
//this.setupPlugins()
|
||||
|
||||
//serializedCompilerArguments.add("-java-parameters")
|
||||
}
|
||||
|
||||
fun Jar.packageDependencies(vararg names: String) {
|
||||
//afterEvaluate {
|
||||
from(*project.configurations.compile.resolvedConfiguration.firstLevelModuleDependencies
|
||||
.filter { it.moduleName in names }
|
||||
.flatMap { it.allModuleArtifacts }
|
||||
.map { it.file }
|
||||
.map(::zipTree)
|
||||
.toTypedArray()
|
||||
)
|
||||
//}
|
||||
}
|
||||
|
||||
fun Jar.packageDependency(name: String, configure: ModuleDependency.() -> Unit) {
|
||||
val configuration = project.configurations.compile.copyRecursive()
|
||||
|
||||
configuration.dependencies.removeIf {
|
||||
if (it is ModuleDependency && it.name == name) {
|
||||
it.configure()
|
||||
false
|
||||
} else true
|
||||
}
|
||||
|
||||
from(*configuration.resolvedConfiguration.resolvedArtifacts
|
||||
.map { it.file }
|
||||
.map(::zipTree)
|
||||
.toTypedArray())
|
||||
}
|
||||
|
||||
fun Jar.packageArtifacts(vararg names: String) {
|
||||
//afterEvaluate {
|
||||
from(*project.configurations.compile.resolvedConfiguration.resolvedArtifacts
|
||||
.filter {
|
||||
val id = it.moduleVersion.id
|
||||
(id.name in names).also {
|
||||
if (!it) stdout.println("Not including artifact: ${id.group}:${id.name}")
|
||||
}
|
||||
}
|
||||
.map { it.file }
|
||||
.map(::zipTree)
|
||||
.toTypedArray())
|
||||
//}
|
||||
}
|
||||
|
||||
val serverDir = "$rootDir/debug"
|
||||
|
||||
val jar by getting(Jar::class)
|
||||
|
||||
val kotlinStdlibJar by creating(Jar::class) {
|
||||
destinationDir = file("$serverDir/lib")
|
||||
archiveName = "kotlin-stdlib.jar"
|
||||
packageDependencies("kotlin-stdlib-jdk8")
|
||||
}
|
||||
|
||||
val shadowJar by getting(ShadowJar::class) {
|
||||
relocate("", "")
|
||||
val debugEnvironment by creating(Exec::class) {
|
||||
|
||||
}
|
||||
|
||||
val releaseJar by creating(ShadowJar::class) {
|
||||
@@ -201,4 +152,56 @@ allprojects {
|
||||
tasks.filter { it is Jar }.forEach { it.group = "artifacts" }
|
||||
}
|
||||
|
||||
stdout.flush()
|
||||
stdout.flush()
|
||||
stdout.close()
|
||||
|
||||
fun Jar.packageDependencies(vararg names: String) {
|
||||
if (!firstImport) {
|
||||
from(*project.configurations.compile.resolvedConfiguration.firstLevelModuleDependencies
|
||||
.filter { it.moduleName in names }
|
||||
.flatMap { it.allModuleArtifacts }
|
||||
.map { it.file }
|
||||
.map(::zipTree)
|
||||
.toTypedArray()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun Jar.packageDependency(name: String, configure: ModuleDependency.() -> Unit) {
|
||||
if (!firstImport) {
|
||||
val configuration = project.configurations.compile.copyRecursive()
|
||||
|
||||
configuration.dependencies.removeIf {
|
||||
if (it is ModuleDependency && it.name == name) {
|
||||
it.configure()
|
||||
false
|
||||
} else true
|
||||
}
|
||||
|
||||
from(*configuration.resolvedConfiguration.resolvedArtifacts
|
||||
.map { it.file }
|
||||
.map(::zipTree)
|
||||
.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("IMPLICIT_CAST_TO_ANY")
|
||||
fun Jar.packageArtifacts(vararg names: String) {
|
||||
if (!firstImport) {
|
||||
from(*project.configurations.compile.resolvedConfiguration.firstLevelModuleDependencies
|
||||
.flatMap { dep -> dep.allModuleArtifacts.map { dep to it } }
|
||||
.filter { pair ->
|
||||
val (dep, art) = pair
|
||||
val id = art.moduleVersion.id
|
||||
(id.name in names).also {
|
||||
val artName = art.moduleVersion.id.let {"${it.group}:${it.name}:${it.version}"}
|
||||
val depName = dep.let { "${it.moduleGroup}:${it.moduleName}:${it.moduleVersion}" }
|
||||
val name = "$artName \n from $depName"
|
||||
stdout.println("${if (it) "Including" else "Not including"} artifact $name")
|
||||
}
|
||||
}
|
||||
.map { pair -> pair.second.file }
|
||||
.map { if (it.isDirectory()) it else zipTree(it) }
|
||||
.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package io.dico.dicore.command;
|
||||
|
||||
public interface ICommandSuspendReceiver extends ICommandReceiver {
|
||||
|
||||
int getTimeout();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package io.dico.dicore.command.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface SuspensionTimeout {
|
||||
// not currently implemented
|
||||
int timeoutMillis();
|
||||
}
|
||||
@@ -26,7 +26,9 @@ fun callAsCoroutine(command: ReflectiveCommand,
|
||||
args: Array<Any?>): String? {
|
||||
val dispatcher = Executor { task -> factory.plugin.server.scheduler.runTask(factory.plugin, task) }.asCoroutineDispatcher()
|
||||
|
||||
// UNDISPATCHED causes the handler to run until the first suspension point on the current thread
|
||||
// UNDISPATCHED causes the handler to run until the first suspension point on the current thread,
|
||||
// meaning command handlers that don't have suspension points will run completely synchronously.
|
||||
// Tasks that take time to compute should suspend the coroutine and resume on another thread.
|
||||
val job = async(context = dispatcher, start = UNDISPATCHED) { command.method.invokeSuspend(command.instance, args) }
|
||||
|
||||
if (job.isCompleted) {
|
||||
@@ -48,11 +50,6 @@ fun callAsCoroutine(command: ReflectiveCommand,
|
||||
|
||||
private suspend fun Method.invokeSuspend(instance: Any?, args: Array<Any?>): Any? {
|
||||
return suspendCoroutineOrReturn { cont ->
|
||||
println()
|
||||
println("Calling command method suspendedly")
|
||||
println(toGenericString())
|
||||
println(Arrays.toString(arrayOf(instance, *args, cont)))
|
||||
println()
|
||||
invoke(instance, *args, cont)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import java.util.*
|
||||
class Options {
|
||||
var worlds: Map<String, WorldOptions> = HashMap()
|
||||
private set
|
||||
var storage: StorageOptions = StorageOptions("mysql", DataConnectionOptions())
|
||||
var storage: StorageOptions = StorageOptions("postgresql", DataConnectionOptions())
|
||||
|
||||
fun addWorld(name: String, options: WorldOptions) = (worlds as MutableMap).put(name, options)
|
||||
|
||||
@@ -90,7 +90,7 @@ data class DataConnectionOptions(val address: String = "localhost",
|
||||
logger.error("(Invalidly) blank address in data storage options")
|
||||
}
|
||||
|
||||
val port = address.substring(idx).toIntOrNull() ?: return null.also {
|
||||
val port = address.substring(idx + 1).toIntOrNull() ?: return null.also {
|
||||
logger.error("Invalid port number in data storage options: $it, using $defaultPort as default")
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,12 @@ class ParcelsPlugin : JavaPlugin() {
|
||||
yamlObjectMapper.readerForUpdating(options).readValue<Options>(optionsFile)
|
||||
} else if (optionsFile.tryCreate()) {
|
||||
options.addWorld("plotworld", WorldOptions())
|
||||
yamlObjectMapper.writeValue(optionsFile, options)
|
||||
try {
|
||||
yamlObjectMapper.writeValue(optionsFile, options)
|
||||
} catch (ex: Throwable) {
|
||||
optionsFile.delete()
|
||||
throw ex
|
||||
}
|
||||
} else {
|
||||
plogger.error("Failed to save options file ${optionsFile.canonicalPath}")
|
||||
return false
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
package io.dico.parcels2.command
|
||||
|
||||
import io.dico.dicore.command.CommandException
|
||||
import io.dico.dicore.command.CommandResult
|
||||
import io.dico.dicore.command.EMessageType
|
||||
import io.dico.dicore.command.ExecutionContext
|
||||
import io.dico.dicore.command.chat.IChatController
|
||||
import io.dico.parcels2.ParcelsPlugin
|
||||
import io.dico.parcels2.logger
|
||||
import kotlinx.coroutines.experimental.*
|
||||
import org.bukkit.command.CommandSender
|
||||
import kotlin.coroutines.experimental.Continuation
|
||||
import kotlin.coroutines.experimental.suspendCoroutine
|
||||
|
||||
/*
|
||||
* Interface to implicitly access plugin by creating extension functions for it
|
||||
*/
|
||||
interface HasPlugin {
|
||||
val plugin: ParcelsPlugin
|
||||
}
|
||||
|
||||
class CommandAsyncScope {
|
||||
|
||||
suspend fun <T> HasPlugin.awaitSynchronousTask(delay: Int = 0, task: () -> T): T {
|
||||
return suspendCoroutine { cont: Continuation<T> ->
|
||||
plugin.server.scheduler.runTaskLater(plugin, l@{
|
||||
val result = try {
|
||||
task()
|
||||
} catch (ex: CommandException) {
|
||||
cont.resumeWithException(ex)
|
||||
return@l
|
||||
} catch (ex: Throwable) {
|
||||
cont.context.cancel(ex)
|
||||
return@l
|
||||
}
|
||||
cont.resume(result)
|
||||
}, delay.toLong())
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> HasPlugin.synchronousTask(delay: Int = 0, task: () -> T): Deferred<T> {
|
||||
return async { awaitSynchronousTask(delay, task) }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun <T : Any?> HasPlugin.delegateCommandAsync(context: ExecutionContext,
|
||||
block: suspend CommandAsyncScope.() -> T) {
|
||||
|
||||
val job: Deferred<Any?> = async(/*context = plugin.storage.asyncDispatcher, */start = CoroutineStart.ATOMIC) {
|
||||
CommandAsyncScope().block()
|
||||
}
|
||||
|
||||
fun Job.invokeOnCompletionSynchronously(block: (Throwable?) -> Unit) = invokeOnCompletion {
|
||||
plugin.server.scheduler.runTask(plugin) { block(it) }
|
||||
}
|
||||
|
||||
job.invokeOnCompletionSynchronously l@{ exception: Throwable? ->
|
||||
exception?.let {
|
||||
context.address.chatController.handleCoroutineException(context.sender, context, it)
|
||||
return@l
|
||||
}
|
||||
|
||||
val result = job.getCompleted()
|
||||
val message = when (result) {
|
||||
is String -> result
|
||||
is CommandResult -> result.message
|
||||
else -> null
|
||||
}
|
||||
|
||||
context.address.chatController.sendMessage(context.sender, EMessageType.RESULT, message)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun IChatController.handleCoroutineException(sender: CommandSender, context: ExecutionContext, exception: Throwable) {
|
||||
if (exception is CancellationException) {
|
||||
sendMessage(sender, EMessageType.EXCEPTION, "The command was cancelled unexpectedly (see console)")
|
||||
logger.warn("An asynchronously dispatched command was cancelled unexpectedly", exception)
|
||||
} else {
|
||||
handleException(sender, context, exception)
|
||||
}
|
||||
}
|
||||
@@ -19,44 +19,28 @@ import kotlin.reflect.jvm.kotlinFunction
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class ParcelRequire(val admin: Boolean = false, val owner: Boolean = false)
|
||||
|
||||
sealed class BaseScope(private var _timeout: Int = 0) : ICommandSuspendReceiver {
|
||||
override fun getTimeout() = _timeout
|
||||
fun setTimeout(timeout: Int) {
|
||||
_timeout = timeout
|
||||
}
|
||||
}
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class SuspensionTimeout(val millis: Int)
|
||||
|
||||
class SuspendOnlyScope : BaseScope()
|
||||
class ParcelScope(val world: ParcelWorld, val parcel: Parcel) : BaseScope()
|
||||
class WorldOnlyScope(val world: ParcelWorld) : BaseScope()
|
||||
open class WorldScope(val world: ParcelWorld) : ICommandReceiver
|
||||
open class ParcelScope(val parcel: Parcel) : WorldScope(parcel.world)
|
||||
|
||||
fun getParcelCommandReceiver(worlds: Worlds, context: ExecutionContext, method: Method, cmdName: String): ICommandReceiver {
|
||||
val player = context.sender as Player
|
||||
val function = method.kotlinFunction!!
|
||||
val receiverType = function.extensionReceiverParameter!!.type
|
||||
logger.info("Receiver type: ${receiverType.javaType.typeName}")
|
||||
|
||||
val require = function.findAnnotation<ParcelRequire>()
|
||||
val admin = require?.admin == true
|
||||
val owner = require?.owner == true
|
||||
|
||||
val player = context.sender as Player
|
||||
|
||||
return when (receiverType.jvmErasure) {
|
||||
ParcelScope::class -> worlds.getParcelRequired(player, admin = admin, own = owner).let {
|
||||
ParcelScope(it.world, it)
|
||||
}
|
||||
WorldOnlyScope::class -> worlds.getWorldRequired(player, admin = admin).let {
|
||||
WorldOnlyScope(it)
|
||||
}
|
||||
SuspendOnlyScope::class -> SuspendOnlyScope()
|
||||
ParcelScope::class -> ParcelScope(worlds.getParcelRequired(player, admin, owner))
|
||||
WorldScope::class -> WorldScope(worlds.getWorldRequired(player, admin))
|
||||
else -> throw InternalError("Invalid command receiver type")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions for checking
|
||||
*/
|
||||
fun Worlds.getWorldRequired(player: Player, admin: Boolean = false): ParcelWorld {
|
||||
if (admin) Validate.isTrue(player.hasAdminManage, "You must have admin rights to use that command")
|
||||
return getWorld(player.world)
|
||||
|
||||
@@ -8,6 +8,7 @@ import io.dico.dicore.command.annotation.Desc
|
||||
import io.dico.dicore.command.annotation.RequireParameters
|
||||
import io.dico.parcels2.ParcelOwner
|
||||
import io.dico.parcels2.ParcelsPlugin
|
||||
import io.dico.parcels2.command.NamedParcelDefaultValue.FIRST_OWNED
|
||||
import io.dico.parcels2.logger
|
||||
import io.dico.parcels2.storage.getParcelBySerializedValue
|
||||
import io.dico.parcels2.util.hasParcelHomeOthers
|
||||
@@ -34,7 +35,7 @@ class ParcelCommands(val plugin: ParcelsPlugin) : ICommandReceiver.Factory {
|
||||
@Desc("Finds the unclaimed parcel nearest to origin,",
|
||||
"and gives it to you",
|
||||
shortVersion = "sets you up with a fresh, unclaimed parcel")
|
||||
suspend fun WorldOnlyScope.cmdAuto(player: Player): Any? {
|
||||
suspend fun WorldScope.cmdAuto(player: Player): Any? {
|
||||
logger.info("cmdAuto thread before await: ${Thread.currentThread().name}")
|
||||
val numOwnedParcels = plugin.storage.getNumParcels(ParcelOwner(uuid = player.uuid)).await()
|
||||
logger.info("cmdAuto thread before await: ${Thread.currentThread().name}")
|
||||
@@ -65,8 +66,9 @@ class ParcelCommands(val plugin: ParcelsPlugin) : ICommandReceiver.Factory {
|
||||
"more than one parcel",
|
||||
shortVersion = "teleports you to parcels")
|
||||
@RequireParameters(0)
|
||||
suspend fun SuspendOnlyScope.cmdHome(player: Player, context: ExecutionContext,
|
||||
@NamedParcelDefault(NamedParcelDefaultValue.FIRST_OWNED) target: NamedParcelTarget): Any? {
|
||||
suspend fun cmdHome(player: Player,
|
||||
@NamedParcelDefault(FIRST_OWNED) target: NamedParcelTarget): Any?
|
||||
{
|
||||
if (player !== target.player && !player.hasParcelHomeOthers) {
|
||||
error("You do not have permission to teleport to other people's parcels")
|
||||
}
|
||||
|
||||
@@ -57,32 +57,30 @@ object ParcelOptionsT : Table("parcel_options") {
|
||||
private class ExposedDatabaseException(message: String? = null) : Exception(message)
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
class ExposedBacking(val dataSource: DataSource) : Backing {
|
||||
class ExposedBacking(private val dataSourceFactory: () -> DataSource) : Backing {
|
||||
override val name get() = "Exposed"
|
||||
private var dataSource: DataSource? = null
|
||||
private var database: Database? = null
|
||||
private var isShutdown: Boolean = false
|
||||
|
||||
override val isConnected get() = database != null
|
||||
|
||||
override suspend fun init() {
|
||||
synchronized {
|
||||
if (isShutdown) throw IllegalStateException()
|
||||
database = Database.connect(dataSource)
|
||||
transaction(database) {
|
||||
create(WorldsT, ParcelsT, AddedLocalT, ParcelOptionsT)
|
||||
}
|
||||
if (isShutdown) throw IllegalStateException()
|
||||
dataSource = dataSourceFactory()
|
||||
database = Database.connect(dataSource!!)
|
||||
transaction(database) {
|
||||
create(WorldsT, ParcelsT, AddedLocalT, ParcelOptionsT)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun shutdown() {
|
||||
synchronized {
|
||||
if (isShutdown) throw IllegalStateException()
|
||||
if (dataSource is HikariDataSource) {
|
||||
dataSource.close()
|
||||
}
|
||||
database = null
|
||||
isShutdown = true
|
||||
if (isShutdown) throw IllegalStateException()
|
||||
dataSource?.let {
|
||||
if (it is HikariDataSource) it.close()
|
||||
}
|
||||
database = null
|
||||
isShutdown = true
|
||||
}
|
||||
|
||||
private fun <T> transaction(statement: Transaction.() -> T) = transaction(database, statement)
|
||||
@@ -206,7 +204,7 @@ class ExposedBacking(val dataSource: DataSource) : Backing {
|
||||
if (data == null) {
|
||||
transaction {
|
||||
getParcelId(parcelFor)?.let { id ->
|
||||
ParcelsT.deleteIgnoreWhere(limit = 1) { ParcelsT.id eq id }
|
||||
ParcelsT.deleteIgnoreWhere() { ParcelsT.id eq id }
|
||||
|
||||
// Below should cascade automatically
|
||||
/*
|
||||
@@ -245,7 +243,7 @@ class ExposedBacking(val dataSource: DataSource) : Backing {
|
||||
else
|
||||
getOrInitParcelId(parcelFor)
|
||||
|
||||
ParcelsT.update({ ParcelsT.id eq id }, limit = 1) {
|
||||
ParcelsT.update({ ParcelsT.id eq id }) {
|
||||
it[ParcelsT.owner_uuid] = binaryUuid
|
||||
it[ParcelsT.owner_name] = name
|
||||
}
|
||||
|
||||
@@ -1,25 +1,34 @@
|
||||
package io.dico.parcels2.storage
|
||||
|
||||
import com.zaxxer.hikari.HikariConfig
|
||||
import com.zaxxer.hikari.HikariDataSource
|
||||
import io.dico.parcels2.DataConnectionOptions
|
||||
import javax.sql.DataSource
|
||||
|
||||
fun getHikariDataSource(dialectName: String,
|
||||
driver: String,
|
||||
dco: DataConnectionOptions): DataSource = with(HikariConfig()) {
|
||||
fun getHikariConfig(dialectName: String,
|
||||
dco: DataConnectionOptions): HikariConfig = HikariConfig().apply {
|
||||
|
||||
val (address, port) = dco.splitAddressAndPort() ?: throw IllegalArgumentException("Invalid address: ${dco.address}")
|
||||
|
||||
poolName = "redstonerplots"
|
||||
when (dialectName) {
|
||||
"postgresql" -> run {
|
||||
dataSourceClassName = "org.postgresql.ds.PGSimpleDataSource"
|
||||
dataSourceProperties["serverName"] = address
|
||||
dataSourceProperties["portNumber"] = port.toString()
|
||||
dataSourceProperties["databaseName"] = dco.database
|
||||
}
|
||||
else -> throw IllegalArgumentException("Unsupported dialect: $dialectName")
|
||||
}
|
||||
|
||||
poolName = "parcels"
|
||||
maximumPoolSize = dco.poolSize
|
||||
dataSourceClassName = driver
|
||||
username = dco.username
|
||||
password = dco.password
|
||||
connectionTimeout = 15000
|
||||
leakDetectionThreshold = 10000
|
||||
connectionTestQuery = "SELECT 1"
|
||||
|
||||
|
||||
/*
|
||||
|
||||
addDataSourceProperty("serverName", address)
|
||||
addDataSourceProperty("port", port.toString())
|
||||
addDataSourceProperty("databaseName", dco.database)
|
||||
@@ -32,7 +41,7 @@ fun getHikariDataSource(dialectName: String,
|
||||
dataSourceProperties.remove("port")
|
||||
dataSourceProperties.remove("databaseName")
|
||||
addDataSourceProperty("url", "jdbc:h2:${if (address.isBlank()) "" else "tcp://$address/"}~/${dco.database}")
|
||||
} else {
|
||||
} else if (dialectName.toLowerCase() == "mysql") {
|
||||
// doesn't exist on the MariaDB driver
|
||||
addDataSourceProperty("cachePrepStmts", "true")
|
||||
addDataSourceProperty("alwaysSendSetIsolation", "false")
|
||||
@@ -49,8 +58,7 @@ fun getHikariDataSource(dialectName: String,
|
||||
// make sure unicode characters can be used.
|
||||
addDataSourceProperty("characterEncoding", "utf8")
|
||||
addDataSourceProperty("useUnicode", "true")
|
||||
}
|
||||
|
||||
HikariDataSource(this)
|
||||
} else {
|
||||
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.dico.parcels2.storage
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource
|
||||
import io.dico.parcels2.DataConnectionOptions
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@@ -26,21 +27,16 @@ interface StorageFactory {
|
||||
|
||||
class ConnectionStorageFactory : StorageFactory {
|
||||
override val optionsClass = DataConnectionOptions::class
|
||||
|
||||
private val types: Map<String, String> = mutableMapOf(
|
||||
"mysql" to "com.mysql.jdbc.jdbc2.optional.MysqlDataSource",
|
||||
"h2" to "org.h2.jdbcx.JdbcDataSource"
|
||||
)
|
||||
private val types: List<String> = listOf("postgresql")
|
||||
|
||||
fun register(companion: StorageFactory.StorageFactories) {
|
||||
types.keys.forEach {
|
||||
companion.registerFactory(it, this)
|
||||
}
|
||||
types.forEach { companion.registerFactory(it, this) }
|
||||
}
|
||||
|
||||
override fun newStorageInstance(dialect: String, options: Any): Storage {
|
||||
val driverClass = types[dialect.toLowerCase()] ?: throw IllegalArgumentException("Storage dialect $dialect is not supported")
|
||||
return StorageWithCoroutineBacking(ExposedBacking(getHikariDataSource(dialect, driverClass, options as DataConnectionOptions)))
|
||||
val hikariConfig = getHikariConfig(dialect, options as DataConnectionOptions)
|
||||
val dataSourceFactory = { HikariDataSource(hikariConfig) }
|
||||
return StorageWithCoroutineBacking(ExposedBacking(dataSourceFactory))
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user