Tweaks and fixes
This commit is contained in:
197
build.gradle.kts
197
build.gradle.kts
@@ -1,25 +1,23 @@
|
||||
@file:Suppress("UNUSED_VARIABLE")
|
||||
@file:Suppress("RemoveRedundantBackticks", "IMPLICIT_CAST_TO_ANY", "UNUSED_VARIABLE")
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.jetbrains.kotlin.gradle.dsl.Coroutines.ENABLE
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformJvmPlugin
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import java.io.PrintWriter
|
||||
|
||||
val firstImport = false
|
||||
val stdout = PrintWriter(File("$rootDir/gradle-output.txt"))
|
||||
|
||||
buildscript {
|
||||
dependencies {
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.51")
|
||||
}
|
||||
}
|
||||
val stdout = PrintWriter("gradle-output.txt")
|
||||
|
||||
group = "io.dico"
|
||||
version = "0.1"
|
||||
|
||||
inline fun <reified T : Plugin<out Project>> Project.apply() =
|
||||
(this as PluginAware).apply<T>()
|
||||
plugins {
|
||||
java
|
||||
kotlin("jvm") version "1.2.51"
|
||||
id("com.github.johnrengelman.plugin-shadow") version "2.0.3"
|
||||
}
|
||||
|
||||
kotlin.experimental.coroutines = ENABLE
|
||||
|
||||
allprojects {
|
||||
apply<JavaPlugin>()
|
||||
@@ -28,76 +26,72 @@ allprojects {
|
||||
mavenCentral()
|
||||
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots")
|
||||
maven("https://hub.spigotmc.org/nexus/content/repositories/sonatype-nexus-snapshots")
|
||||
maven("https://dl.bintray.com/kotlin/exposed")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
val spigotVersion = "1.13-R0.1-SNAPSHOT"
|
||||
compile("org.bukkit:bukkit:$spigotVersion") { isTransitive = false }
|
||||
compile("org.spigotmc:spigot-api:$spigotVersion") { isTransitive = false }
|
||||
c.provided("org.bukkit:bukkit:$spigotVersion") { isTransitive = false }
|
||||
c.provided("org.spigotmc:spigot-api:$spigotVersion") { isTransitive = false }
|
||||
|
||||
compile("net.sf.trove4j:trove4j:3.0.3")
|
||||
c.provided("net.sf.trove4j:trove4j:3.0.3")
|
||||
testCompile("junit:junit:4.12")
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
tasks.filter { it is Jar }.forEach { it.group = "artifacts" }
|
||||
}
|
||||
}
|
||||
|
||||
project(":dicore3:dicore3-command") {
|
||||
apply<KotlinPlatformJvmPlugin>()
|
||||
|
||||
kotlin.experimental.coroutines = ENABLE
|
||||
|
||||
dependencies {
|
||||
// why the fuck does it need reflect explicitly?
|
||||
compile("org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.4")
|
||||
compile(kotlin("reflect", version = "1.2.50"))
|
||||
compile(kotlin("stdlib-jdk8", version = "1.2.51"))
|
||||
c.kotlinStd(kotlin("stdlib-jdk8"))
|
||||
c.kotlinStd(kotlin("reflect"))
|
||||
c.kotlinStd(kotlinx("coroutines-core:0.23.4"))
|
||||
|
||||
compile(project(":dicore3:dicore3-core"))
|
||||
compile("com.thoughtworks.paranamer:paranamer:2.8")
|
||||
c.provided("com.google.guava:guava:25.1-jre")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "1.2.51"
|
||||
id("com.github.johnrengelman.plugin-shadow") version "2.0.3"
|
||||
}
|
||||
|
||||
kotlin.experimental.coroutines = ENABLE
|
||||
|
||||
repositories {
|
||||
maven("https://dl.bintray.com/kotlin/exposed")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile(project(":dicore3:dicore3-core"))
|
||||
compile(project(":dicore3:dicore3-command"))
|
||||
compile(kotlin("stdlib-jdk8"))
|
||||
|
||||
compile("org.jetbrains.exposed:exposed:0.10.3")
|
||||
compile("org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.4")
|
||||
c.kotlinStd(kotlin("stdlib-jdk8"))
|
||||
c.kotlinStd(kotlinx("coroutines-core:0.23.4"))
|
||||
c.kotlinStd("org.jetbrains.exposed:exposed:0.10.3")
|
||||
|
||||
compile("com.zaxxer:HikariCP:3.2.0")
|
||||
compile("com.h2database:h2:1.4.197")
|
||||
|
||||
val jacksonVersion = "2.9.6"
|
||||
compile("com.fasterxml.jackson.core:jackson-core:$jacksonVersion")
|
||||
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")
|
||||
compile("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonVersion") { isTransitive = false }
|
||||
}
|
||||
|
||||
tasks {
|
||||
removeIf { it is ShadowJar }
|
||||
|
||||
val compileKotlin by getting(KotlinCompile::class) {
|
||||
kotlinOptions {
|
||||
javaParameters = true
|
||||
}
|
||||
}
|
||||
|
||||
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 debugEnvironment by creating(Exec::class) {
|
||||
|
||||
fromFiles(c.kotlinStd)
|
||||
}
|
||||
|
||||
val releaseJar by creating(ShadowJar::class) {
|
||||
@@ -105,103 +99,46 @@ tasks {
|
||||
baseName = "parcels2-release"
|
||||
|
||||
with(jar)
|
||||
fromFiles(c.compile)
|
||||
|
||||
packageArtifacts(
|
||||
"jackson-core",
|
||||
"jackson-databind",
|
||||
"jackson-module-kotlin",
|
||||
"jackson-annotations",
|
||||
"jackson-dataformat-yaml",
|
||||
"snakeyaml",
|
||||
/*
|
||||
Shadow Jar is retarded so it also relocates packages not included in the releaseJar (such as the bukkit api)
|
||||
|
||||
"slf4j-api",
|
||||
"logback-core",
|
||||
"logback-classic",
|
||||
relocate("", "io.dico.parcels2.lib.") {
|
||||
exclude("*yml")
|
||||
exclude("*xml")
|
||||
exclude("META-INF/*")
|
||||
exclude("io/dico/*")
|
||||
}
|
||||
*/*/*/
|
||||
|
||||
//"h2",
|
||||
"HikariCP",
|
||||
"kotlinx-coroutines-core",
|
||||
"kotlinx-coroutines-core-common",
|
||||
"atomicfu-common",
|
||||
"exposed",
|
||||
// jackson-dataformat-yaml requires an older version of snakeyaml (1.19 or earlier)
|
||||
// snakeyaml made a breaking change in 1.20 and didn't really warn anyone afaik
|
||||
// it was like me changing the command library because I know I'm the only one using it
|
||||
// spigot ships a later version in the root, so we must relocate ours
|
||||
relocate("org.yaml.snakeyaml.", "io.dico.parcels2.lib.org.yaml.snakeyaml.")
|
||||
|
||||
"dicore3-core",
|
||||
"dicore3-command",
|
||||
"paranamer",
|
||||
|
||||
"trove4j",
|
||||
"joda-time",
|
||||
|
||||
"annotations",
|
||||
"kotlin-stdlib-common",
|
||||
"kotlin-stdlib",
|
||||
"kotlin-stdlib-jdk7",
|
||||
"kotlin-stdlib-jdk8",
|
||||
"kotlin-reflect"
|
||||
)
|
||||
|
||||
relocate("org.yaml.snakeyaml", "io.dico.parcels2.util.snakeyaml")
|
||||
|
||||
manifest.attributes["Class-Path"] = "lib/kotlin-stdlib.jar"
|
||||
manifest.attributes["Class-Path"] = "../lib/kotlin-stdlib.jar"
|
||||
dependsOn(kotlinStdlibJar)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
allprojects {
|
||||
tasks.filter { it is Jar }.forEach { it.group = "artifacts" }
|
||||
}
|
||||
|
||||
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()
|
||||
)
|
||||
}
|
||||
}
|
||||
inline fun <reified T : Plugin<out Project>> Project.apply() =
|
||||
(this as PluginAware).apply<T>()
|
||||
|
||||
fun Jar.packageDependency(name: String, configure: ModuleDependency.() -> Unit) {
|
||||
if (!firstImport) {
|
||||
val configuration = project.configurations.compile.copyRecursive()
|
||||
fun kotlinx(module: String, version: String? = null): Any =
|
||||
"org.jetbrains.kotlinx:kotlinx-$module${version?.let { ":$version" } ?: ""}"
|
||||
|
||||
configuration.dependencies.removeIf {
|
||||
if (it is ModuleDependency && it.name == name) {
|
||||
it.configure()
|
||||
false
|
||||
} else true
|
||||
}
|
||||
val Project.c get() = configurations
|
||||
|
||||
from(*configuration.resolvedConfiguration.resolvedArtifacts
|
||||
.map { it.file }
|
||||
.map(::zipTree)
|
||||
.toTypedArray())
|
||||
}
|
||||
}
|
||||
val ConfigurationContainer.`provided`: Configuration
|
||||
get() = findByName("provided") ?: create("provided").let { compileClasspath.extendsFrom(it) }
|
||||
|
||||
@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())
|
||||
}
|
||||
}
|
||||
val ConfigurationContainer.`kotlinStd`: Configuration
|
||||
get() = findByName("kotlinStd") ?: create("kotlinStd").let { compileClasspath.extendsFrom(it) }
|
||||
|
||||
fun Jar.fromFiles(files: Iterable<File>) =
|
||||
afterEvaluate { from(*files.map { if (it.isDirectory) it else zipTree(it) }.toTypedArray()) }
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import org.jetbrains.kotlin.gradle.dsl.Coroutines
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer.kotlin
|
||||
|
||||
group = "io.dico.dicore3"
|
||||
//name = "dicore3-command"
|
||||
version = "1.2.5-mc-1.13"
|
||||
|
||||
@@ -27,27 +27,27 @@ public abstract class Command {
|
||||
}
|
||||
|
||||
public <TType> Command addParameter(String name, String description, ParameterType<TType, Void> type) {
|
||||
return addParameter(Parameter.newParameter(name, description, type, null, false, null));
|
||||
return addParameter(new Parameter<>(name, description, type, null, false, null));
|
||||
}
|
||||
|
||||
public <TType, TParamInfo> Command addParameter(String name, String description, ParameterType<TType, TParamInfo> type, TParamInfo paramInfo) {
|
||||
return addParameter(Parameter.newParameter(name, description, type, paramInfo, false, null));
|
||||
return addParameter(new Parameter<>(name, description, type, paramInfo, false, null));
|
||||
}
|
||||
|
||||
public <TType> Command addFlag(String name, String description, ParameterType<TType, Void> type) {
|
||||
return addParameter(Parameter.newParameter('-' + name, description, type, null, true, null));
|
||||
return addParameter(new Parameter<>('-' + name, description, type, null, true, null));
|
||||
}
|
||||
|
||||
public <TType, TParamInfo> Command addFlag(String name, String description, ParameterType<TType, TParamInfo> type, TParamInfo paramInfo) {
|
||||
return addParameter(Parameter.newParameter('-' + name, description, type, paramInfo, true, null));
|
||||
return addParameter(new Parameter<>('-' + name, description, type, paramInfo, true, null));
|
||||
}
|
||||
|
||||
public <TType> Command addAuthorizedFlag(String name, String description, ParameterType<TType, Void> type, String permission) {
|
||||
return addParameter(Parameter.newParameter('-' + name, description, type, null, true, permission));
|
||||
return addParameter(new Parameter<>('-' + name, description, type, null, true, permission));
|
||||
}
|
||||
|
||||
public <TType, TParamInfo> Command addAuthorizedFlag(String name, String description, ParameterType<TType, TParamInfo> type, TParamInfo paramInfo, String permission) {
|
||||
return addParameter(Parameter.newParameter('-' + name, description, type, paramInfo, true, permission));
|
||||
return addParameter(new Parameter<>('-' + name, description, type, paramInfo, true, permission));
|
||||
}
|
||||
|
||||
public Command requiredParameters(int requiredParameters) {
|
||||
|
||||
@@ -153,14 +153,7 @@ public final class CommandBuilder {
|
||||
* @return this
|
||||
*/
|
||||
public CommandBuilder generatePredefinedCommands(String... commands) {
|
||||
for (String value : commands) {
|
||||
Consumer<ICommandAddress> subscriber = PredefinedCommand.getPredefinedCommandGenerator(value);
|
||||
if (subscriber == null) {
|
||||
System.out.println("[Command Warning] generated command '" + value + "' could not be found");
|
||||
} else {
|
||||
subscriber.accept(cur);
|
||||
}
|
||||
}
|
||||
ReflectiveRegistration.generateCommands(cur, commands);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ public class Parameter<TResult, TParamInfo> {
|
||||
private final String description;
|
||||
private final ParameterType<TResult, TParamInfo> parameterType;
|
||||
private final TParamInfo paramInfo;
|
||||
private final boolean isPrimitive;
|
||||
|
||||
private final boolean flag;
|
||||
private final String flagPermission;
|
||||
|
||||
@@ -29,6 +31,10 @@ public class Parameter<TResult, TParamInfo> {
|
||||
}
|
||||
|
||||
public Parameter(String name, String description, ParameterType<TResult, TParamInfo> parameterType, TParamInfo paramInfo, boolean flag, String flagPermission) {
|
||||
this(name, description, parameterType, paramInfo, false, flag, flagPermission);
|
||||
}
|
||||
|
||||
public Parameter(String name, String description, ParameterType<TResult, TParamInfo> parameterType, TParamInfo paramInfo, boolean isPrimitive, boolean flag, String flagPermission) {
|
||||
this.name = Objects.requireNonNull(name);
|
||||
this.description = description == null ? "" : description;
|
||||
this.parameterType = flag ? parameterType.asFlagParameter() : parameterType;
|
||||
@@ -38,6 +44,7 @@ public class Parameter<TResult, TParamInfo> {
|
||||
}
|
||||
*/
|
||||
this.paramInfo = paramInfo;
|
||||
this.isPrimitive = isPrimitive;
|
||||
|
||||
this.flag = flag;
|
||||
this.flagPermission = flagPermission;
|
||||
@@ -49,17 +56,7 @@ public class Parameter<TResult, TParamInfo> {
|
||||
}
|
||||
}
|
||||
|
||||
public static <TResult> Parameter<TResult, ?> newParameter(String name, String description, ParameterType<TResult, ?> type) {
|
||||
return new Parameter<>(name, description, type, null);
|
||||
}
|
||||
|
||||
public static <TResult, TParamInfo> Parameter<TResult, TParamInfo> newParameter(String name, String description, ParameterType<TResult, TParamInfo> type, TParamInfo info) {
|
||||
return new Parameter<>(name, description, type, info);
|
||||
}
|
||||
|
||||
public static <TResult, TParamInfo> Parameter<TResult, TParamInfo> newParameter(String name, String description, ParameterType<TResult, TParamInfo> parameterType, TParamInfo paramInfo, boolean flag, String flagPermission) {
|
||||
return new Parameter<>(name, description, parameterType, paramInfo, flag, flagPermission);
|
||||
}
|
||||
|
||||
public TResult parse(ExecutionContext context, ArgumentBuffer buffer) throws CommandException {
|
||||
if (getFlagPermission() != null) {
|
||||
@@ -96,6 +93,10 @@ public class Parameter<TResult, TParamInfo> {
|
||||
return paramInfo;
|
||||
}
|
||||
|
||||
public boolean isPrimitive() {
|
||||
return isPrimitive;
|
||||
}
|
||||
|
||||
public boolean isFlag() {
|
||||
return flag;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,8 @@ public abstract class NumberParameterType<T extends Number> extends ParameterTyp
|
||||
@Override
|
||||
public T getDefaultValue(Parameter<T, Range.Memory> parameter, CommandSender sender, ArgumentBuffer buffer) throws CommandException {
|
||||
Range.Memory memory = (Range.Memory) parameter.getParamInfo();
|
||||
return select(memory != null ? memory.defaultValue() : 0);
|
||||
if (memory != null) return select(memory.defaultValue());
|
||||
return !parameter.isPrimitive() ? null : select(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package io.dico.dicore.command.parameter.type;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -7,16 +11,28 @@ import java.util.Objects;
|
||||
* More appropriate name: ParameterTypeKey
|
||||
*/
|
||||
public class ParameterKey {
|
||||
|
||||
private final Class<?> returnType;
|
||||
private final Class<? extends Annotation> annotationClass;
|
||||
|
||||
// just a marker, not used in equals or hashCode().
|
||||
// returnType is never primitive
|
||||
private boolean isPrimitive;
|
||||
|
||||
public ParameterKey(Class<?> returnType) {
|
||||
this(returnType, null);
|
||||
}
|
||||
|
||||
public ParameterKey(Class<?> returnType, Class<? extends Annotation> annotationClass) {
|
||||
boolean isPrimitive = returnType.isPrimitive();
|
||||
|
||||
if (isPrimitive) {
|
||||
returnType = primitivesToWrappers.get(returnType);
|
||||
}
|
||||
|
||||
this.returnType = Objects.requireNonNull(returnType);
|
||||
this.annotationClass = annotationClass;
|
||||
this.isPrimitive = isPrimitive;
|
||||
}
|
||||
|
||||
public Class<?> getReturnType() {
|
||||
@@ -43,4 +59,45 @@ public class ParameterKey {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Class<?> getPrimitiveWrapperClass(Class<?> primitiveClass) {
|
||||
if (!primitiveClass.isPrimitive()) return null;
|
||||
switch (primitiveClass.getName()) {
|
||||
case "boolean":
|
||||
return Boolean.class;
|
||||
case "char":
|
||||
return Character.class;
|
||||
case "byte":
|
||||
return Byte.class;
|
||||
case "short":
|
||||
return Short.class;
|
||||
case "int":
|
||||
return Integer.class;
|
||||
case "float":
|
||||
return Float.class;
|
||||
case "long":
|
||||
return Long.class;
|
||||
case "double":
|
||||
return Double.class;
|
||||
case "void":
|
||||
return Void.class;
|
||||
default:
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
private static final BiMap<Class<?>, Class<?>> primitivesToWrappers;
|
||||
static {
|
||||
HashBiMap<Class<?>, Class<?>> tmp = HashBiMap.create();
|
||||
tmp.put(Boolean.TYPE, Boolean.class);
|
||||
tmp.put(Character.TYPE, Character.class);
|
||||
tmp.put(Byte.TYPE, Byte.class);
|
||||
tmp.put(Short.TYPE, Short.class);
|
||||
tmp.put(Integer.TYPE, Integer.class);
|
||||
tmp.put(Float.TYPE, Float.class);
|
||||
tmp.put(Long.TYPE, Long.class);
|
||||
tmp.put(Double.TYPE, Double.class);
|
||||
tmp.put(Void.TYPE, Void.class);
|
||||
primitivesToWrappers = Maps.unmodifiableBiMap(tmp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,9 +42,6 @@ public class ParameterTypes {
|
||||
public static final NumberParameterType<Float> FLOAT;
|
||||
public static final ParameterType<Player, Void> PLAYER;
|
||||
public static final ParameterType<OfflinePlayer, Void> OFFLINE_PLAYER;
|
||||
//public static final ParameterType<Boolean, Void> PRESENCE;
|
||||
//public static final NumberParameterType<BigDecimal> BIG_DECIMAL;
|
||||
//public static final NumberParameterType<BigInteger> BIG_INTEGER;
|
||||
|
||||
private ParameterTypes() {
|
||||
|
||||
@@ -59,7 +56,7 @@ public class ParameterTypes {
|
||||
|
||||
@Override
|
||||
public String getDefaultValue(Parameter<String, Void> parameter, CommandSender sender, ArgumentBuffer buffer) throws CommandException {
|
||||
return "";
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -81,7 +78,7 @@ public class ParameterTypes {
|
||||
|
||||
@Override
|
||||
public Boolean getDefaultValue(Parameter<Boolean, Void> parameter, CommandSender sender, ArgumentBuffer buffer) throws CommandException {
|
||||
return false;
|
||||
return !parameter.isPrimitive() ? null : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package io.dico.dicore.command.predef;
|
||||
|
||||
public class HelpCommandExtended {
|
||||
|
||||
// TODO
|
||||
|
||||
}
|
||||
@@ -332,7 +332,7 @@ public class ReflectiveRegistration {
|
||||
|
||||
ParameterType<Object, Object> parameterType = selector.selectAny(type, typeAnnotation == null ? null : typeAnnotation.getClass());
|
||||
if (parameterType == null) {
|
||||
throw new CommandParseException("IParameter type not found for parameter " + name + " in method " + method.toGenericString());
|
||||
throw new CommandParseException("IParameter type not found for parameter " + name + " in method " + method.toString());
|
||||
}
|
||||
|
||||
Object parameterInfo;
|
||||
@@ -348,7 +348,8 @@ public class ReflectiveRegistration {
|
||||
|
||||
try {
|
||||
//noinspection unchecked
|
||||
return Parameter.newParameter(name, descString, parameterType, parameterInfo, name.startsWith("-"), flag == null ? null : flag.permission());
|
||||
String flagPermission = flag == null ? null : flag.permission();
|
||||
return new Parameter<>(name, descString, parameterType, parameterInfo, type.isPrimitive(), name.startsWith("-"), flagPermission);
|
||||
} catch (Exception ex) {
|
||||
throw new CommandParseException("Invalid parameter", ex);
|
||||
}
|
||||
|
||||
@@ -66,4 +66,11 @@ private fun Deferred<Any?>.getResult(): String? {
|
||||
throw ex
|
||||
}
|
||||
return ReflectiveCommand.getResult(getCompleted(), null)
|
||||
}
|
||||
|
||||
fun getNonPrimitiveClass(clazz: Class<*>): Class<*>? {
|
||||
return if (clazz.isPrimitive)
|
||||
clazz.kotlin.javaObjectType
|
||||
else
|
||||
null
|
||||
}
|
||||
@@ -2,15 +2,3 @@
|
||||
group = "io.dico.dicore3"
|
||||
version = "1.2.5"
|
||||
|
||||
plugins {
|
||||
java
|
||||
}
|
||||
|
||||
repositories() {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile(files("../../res/spigot-1.13-pre7.jar"))
|
||||
|
||||
}
|
||||
206
old-build.gradle.kts
Normal file
206
old-build.gradle.kts
Normal file
@@ -0,0 +1,206 @@
|
||||
@file:Suppress("UNUSED_VARIABLE")
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.jetbrains.kotlin.gradle.dsl.Coroutines.ENABLE
|
||||
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 {
|
||||
dependencies {
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.51")
|
||||
}
|
||||
}
|
||||
|
||||
group = "io.dico"
|
||||
version = "0.1"
|
||||
|
||||
inline fun <reified T : Plugin<out Project>> Project.apply() =
|
||||
(this as PluginAware).apply<T>()
|
||||
|
||||
allprojects {
|
||||
apply<JavaPlugin>()
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots")
|
||||
maven("https://hub.spigotmc.org/nexus/content/repositories/sonatype-nexus-snapshots")
|
||||
}
|
||||
dependencies {
|
||||
val spigotVersion = "1.13-R0.1-SNAPSHOT"
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
project(":dicore3:dicore3-command") {
|
||||
apply<KotlinPlatformJvmPlugin>()
|
||||
|
||||
kotlin.experimental.coroutines = ENABLE
|
||||
|
||||
dependencies {
|
||||
compile("org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.4")
|
||||
compile(kotlin("reflect", version = "1.2.50"))
|
||||
compile(kotlin("stdlib-jdk8", version = "1.2.51"))
|
||||
compile(project(":dicore3:dicore3-core"))
|
||||
compile("com.thoughtworks.paranamer:paranamer:2.8")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "1.2.51"
|
||||
id("com.github.johnrengelman.plugin-shadow") version "2.0.3"
|
||||
}
|
||||
|
||||
kotlin.experimental.coroutines = ENABLE
|
||||
|
||||
repositories {
|
||||
maven("https://dl.bintray.com/kotlin/exposed")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile(project(":dicore3:dicore3-core"))
|
||||
compile(project(":dicore3:dicore3-command"))
|
||||
compile(kotlin("stdlib-jdk8"))
|
||||
|
||||
compile("org.jetbrains.exposed:exposed:0.10.3")
|
||||
compile("org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.4")
|
||||
compile("com.zaxxer:HikariCP:3.2.0")
|
||||
compile("com.h2database:h2:1.4.197")
|
||||
|
||||
val jacksonVersion = "2.9.6"
|
||||
compile("com.fasterxml.jackson.core:jackson-core:$jacksonVersion")
|
||||
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 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 debugEnvironment by creating(Exec::class) {
|
||||
|
||||
}
|
||||
|
||||
val releaseJar by creating(ShadowJar::class) {
|
||||
destinationDir = file("$serverDir/plugins")
|
||||
baseName = "parcels2-release"
|
||||
|
||||
with(jar)
|
||||
|
||||
packageArtifacts(
|
||||
"jackson-core",
|
||||
"jackson-databind",
|
||||
"jackson-module-kotlin",
|
||||
"jackson-annotations",
|
||||
"jackson-dataformat-yaml",
|
||||
"snakeyaml",
|
||||
|
||||
"slf4j-api",
|
||||
"logback-core",
|
||||
"logback-classic",
|
||||
|
||||
//"h2",
|
||||
"HikariCP",
|
||||
"kotlinx-coroutines-core",
|
||||
"kotlinx-coroutines-core-common",
|
||||
"atomicfu-common",
|
||||
"exposed",
|
||||
|
||||
"dicore3-core",
|
||||
"dicore3-command",
|
||||
"paranamer",
|
||||
|
||||
"trove4j",
|
||||
"joda-time",
|
||||
|
||||
"annotations",
|
||||
"kotlin-stdlib-common",
|
||||
"kotlin-stdlib",
|
||||
"kotlin-stdlib-jdk7",
|
||||
"kotlin-stdlib-jdk8",
|
||||
"kotlin-reflect"
|
||||
)
|
||||
|
||||
relocate("org.yaml.snakeyaml", "io.dico.parcels2.util.snakeyaml")
|
||||
|
||||
manifest.attributes["Class-Path"] = "lib/kotlin-stdlib.jar"
|
||||
dependsOn(kotlinStdlibJar)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
allprojects {
|
||||
tasks.filter { it is Jar }.forEach { it.group = "artifacts" }
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import org.bukkit.block.Block
|
||||
import org.bukkit.entity.Entity
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.*
|
||||
import kotlin.coroutines.experimental.buildIterator
|
||||
import kotlin.coroutines.experimental.buildSequence
|
||||
import kotlin.reflect.jvm.javaMethod
|
||||
import kotlin.reflect.jvm.kotlinFunction
|
||||
@@ -117,7 +118,9 @@ class ParcelWorld constructor(val name: String,
|
||||
val options: WorldOptions,
|
||||
val generator: ParcelGenerator,
|
||||
val storage: Storage) : ParcelProvider by generator, ParcelContainer {
|
||||
val world: World by lazy { Bukkit.getWorld(name) ?: throw NullPointerException("World $name does not appear to be loaded") }
|
||||
val world: World by lazy {
|
||||
Bukkit.getWorld(name) ?: throw NullPointerException("World $name does not appear to be loaded")
|
||||
}
|
||||
val container: ParcelContainer = DefaultParcelContainer(this, storage)
|
||||
|
||||
override fun parcelByID(x: Int, z: Int): Parcel? {
|
||||
@@ -189,12 +192,24 @@ class DefaultParcelContainer(private val world: ParcelWorld,
|
||||
}
|
||||
|
||||
override fun parcelByID(x: Int, z: Int): Parcel? {
|
||||
return parcels.getOrNull(x)?.getOrNull(z)
|
||||
return parcels.getOrNull(x + world.options.axisLimit)?.getOrNull(z + world.options.axisLimit)
|
||||
}
|
||||
|
||||
override fun nextEmptyParcel(): Parcel? {
|
||||
return parcels[0][0]
|
||||
TODO()
|
||||
return walkInCircle().find { it.owner == null }
|
||||
}
|
||||
|
||||
private fun walkInCircle(): Iterable<Parcel> = Iterable {
|
||||
buildIterator {
|
||||
val center = world.options.axisLimit
|
||||
for (radius in 0..center) {
|
||||
var x = center - radius; var z = center - radius
|
||||
repeat(radius * 2) { yield(parcels[x++][z]) }
|
||||
repeat(radius * 2) { yield(parcels[x][z++]) }
|
||||
repeat(radius * 2) { yield(parcels[x--][z]) }
|
||||
repeat(radius * 2) { yield(parcels[x][z--]) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun allParcels(): Sequence<Parcel> = buildSequence {
|
||||
|
||||
@@ -194,7 +194,7 @@ class DefaultParcelGenerator(val worlds: Worlds, val name: String, private val o
|
||||
val signBlock = world.getBlockAt(b.x - 2, o.floorHeight + 1, b.z - 1)
|
||||
val skullBlock = world.getBlockAt(b.x - 1, o.floorHeight + 2, b.z - 1)
|
||||
|
||||
val owner = parcel.data?.owner
|
||||
val owner = parcel.owner
|
||||
if (owner == null) {
|
||||
wallBlock.blockData = o.wallType
|
||||
signBlock.type = Material.AIR
|
||||
|
||||
@@ -25,6 +25,7 @@ class CommandsParcelOptions(plugin: ParcelsPlugin) : AbstractParcelCommands(plug
|
||||
@Desc("Sets whether players who are not allowed to",
|
||||
"build here can interact with inventories",
|
||||
shortVersion = "allows editing inventories")
|
||||
@RequireParameters(0)
|
||||
fun ParcelScope.cmdInventory(player: Player, enabled: Boolean?): Any? {
|
||||
return runOptionCommand(player, Parcel::allowInteractInventory, enabled, "interaction with inventories")
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package io.dico.parcels2.command
|
||||
|
||||
import io.dico.dicore.command.CommandBuilder
|
||||
import io.dico.dicore.command.ICommandAddress
|
||||
import io.dico.dicore.command.ICommandDispatcher
|
||||
import io.dico.dicore.command.predef.PredefinedCommand
|
||||
import io.dico.dicore.command.registration.reflect.ReflectiveRegistration
|
||||
import io.dico.parcels2.ParcelsPlugin
|
||||
import io.dico.parcels2.logger
|
||||
import java.util.*
|
||||
|
||||
@Suppress("UsePropertyAccessSyntax")
|
||||
fun getParcelCommands(plugin: ParcelsPlugin): ICommandDispatcher {
|
||||
@@ -18,7 +22,7 @@ fun getParcelCommands(plugin: ParcelsPlugin): ICommandDispatcher {
|
||||
.registerCommands(CommandsAddedStatus(plugin))
|
||||
|
||||
.group("option")
|
||||
.apply { CommandsParcelOptions.setGroupDescription(this) }
|
||||
//.apply { CommandsParcelOptions.setGroupDescription(this) }
|
||||
.registerCommands(CommandsParcelOptions(plugin))
|
||||
.parent()
|
||||
|
||||
@@ -29,15 +33,34 @@ fun getParcelCommands(plugin: ParcelsPlugin): ICommandDispatcher {
|
||||
.putDebugCommands(plugin)
|
||||
|
||||
.parent()
|
||||
.generateHelpAndSyntaxCommands()
|
||||
.getDispatcher()
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
private fun CommandBuilder.putDebugCommands(plugin: ParcelsPlugin): CommandBuilder {
|
||||
if (!logger.isDebugEnabled) return this
|
||||
//if (!logger.isDebugEnabled) return this
|
||||
//@formatter:off
|
||||
return group("debug", "d")
|
||||
.registerCommands(CommandsDebug(plugin))
|
||||
.parent()
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
private fun CommandBuilder.generateHelpAndSyntaxCommands(): CommandBuilder {
|
||||
generateCommands(dispatcher as ICommandAddress, "help", "syntax")
|
||||
return this
|
||||
}
|
||||
|
||||
private fun generateCommands(address: ICommandAddress, vararg names: String) {
|
||||
val addresses: Queue<ICommandAddress> = LinkedList()
|
||||
addresses.offer(address)
|
||||
|
||||
while (addresses.isNotEmpty()) {
|
||||
val cur = addresses.poll()
|
||||
addresses.addAll(cur.children.values.distinct())
|
||||
if (cur.hasCommand()) {
|
||||
ReflectiveRegistration.generateCommands(cur, names)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,42 +17,39 @@ object WorldsT : Table("worlds") {
|
||||
val id = integer("world_id").autoIncrement().primaryKey()
|
||||
val name = varchar("name", 50)
|
||||
val uid = binary("uid", 16)
|
||||
.also { uniqueIndex("index_uid", it) }
|
||||
val index_uid = uniqueIndexR("index_uid", uid)
|
||||
}
|
||||
|
||||
object ParcelsT : Table("parcels") {
|
||||
val id = integer("parcel_id").autoIncrement().primaryKey()
|
||||
val px = integer("px")
|
||||
val pz = integer("pz")
|
||||
val world_id = integer("id")
|
||||
.also { uniqueIndex("index_location", it, px, pz) }
|
||||
.references(WorldsT.id)
|
||||
val world_id = integer("world_id").references(WorldsT.id)
|
||||
val owner_uuid = binary("owner_uuid", 16).nullable()
|
||||
val owner_name = varchar("owner_name", 16).nullable()
|
||||
val claim_time = datetime("claim_time").nullable()
|
||||
val index_location = uniqueIndexR("index_location", world_id, px, pz)
|
||||
}
|
||||
|
||||
object AddedLocalT : Table("parcels_added_local") {
|
||||
val parcel_id = integer("parcel_id")
|
||||
.references(ParcelsT.id, ReferenceOption.CASCADE)
|
||||
val parcel_id = integer("parcel_id").references(ParcelsT.id, ReferenceOption.CASCADE)
|
||||
val player_uuid = binary("player_uuid", 16)
|
||||
.also { uniqueIndex("index_pair", parcel_id, it) }
|
||||
val allowed_flag = bool("allowed_flag")
|
||||
val index_pair = uniqueIndexR("index_pair", parcel_id, player_uuid)
|
||||
}
|
||||
|
||||
object AddedGlobalT : Table("parcels_added_global") {
|
||||
val owner_uuid = binary("owner_uuid", 16)
|
||||
val player_uuid = binary("player_uuid", 16)
|
||||
.also { uniqueIndex("index_pair", owner_uuid, it) }
|
||||
val allowed_flag = bool("allowed_flag")
|
||||
val index_pair = uniqueIndexR("index_pair", owner_uuid, player_uuid)
|
||||
}
|
||||
|
||||
object ParcelOptionsT : Table("parcel_options") {
|
||||
val parcel_id = integer("parcel_id")
|
||||
.also { uniqueIndex("index_parcel_id", it) }
|
||||
.references(ParcelsT.id, ReferenceOption.CASCADE)
|
||||
val parcel_id = integer("parcel_id").references(ParcelsT.id, ReferenceOption.CASCADE)
|
||||
val interact_inventory = bool("interact_inventory").default(false)
|
||||
val interact_inputs = bool("interact_inputs").default(false)
|
||||
val index_parcel_id = uniqueIndexR("index_parcel_id", parcel_id)
|
||||
}
|
||||
|
||||
private class ExposedDatabaseException(message: String? = null) : Exception(message)
|
||||
@@ -163,7 +160,6 @@ class ExposedBacking(private val dataSourceFactory: () -> DataSource) : Backing
|
||||
rowToParcelData(row)
|
||||
}
|
||||
|
||||
// TODO order by some new column
|
||||
override suspend fun getOwnedParcels(user: ParcelOwner): List<SerializableParcel> = transaction {
|
||||
val where: SqlExpressionBuilder.() -> Op<Boolean>
|
||||
|
||||
@@ -175,7 +171,8 @@ class ExposedBacking(private val dataSourceFactory: () -> DataSource) : Backing
|
||||
where = { ParcelsT.owner_name eq name }
|
||||
}
|
||||
|
||||
ParcelsT.select(where).orderBy(ParcelsT.claim_time, isAsc = true)
|
||||
ParcelsT.select(where)
|
||||
.orderBy(ParcelsT.claim_time, isAsc = true)
|
||||
.mapNotNull(::rowToSerializableParcel)
|
||||
.toList()
|
||||
}
|
||||
@@ -243,7 +240,7 @@ class ExposedBacking(private val dataSourceFactory: () -> DataSource) : Backing
|
||||
}
|
||||
|
||||
val id = getOrInitParcelId(parcelFor)
|
||||
AddedLocalT.insertOrUpdate(AddedLocalT.allowed_flag) {
|
||||
AddedLocalT.upsert(AddedLocalT.parcel_id) {
|
||||
it[AddedLocalT.parcel_id] = id
|
||||
it[AddedLocalT.player_uuid] = binaryUuid
|
||||
}
|
||||
@@ -251,7 +248,7 @@ class ExposedBacking(private val dataSourceFactory: () -> DataSource) : Backing
|
||||
|
||||
override suspend fun setParcelAllowsInteractInventory(parcel: Parcel, value: Boolean): Unit = transaction {
|
||||
val id = getOrInitParcelId(parcel)
|
||||
ParcelOptionsT.insertOrUpdate(ParcelOptionsT.interact_inventory) {
|
||||
ParcelOptionsT.upsert(ParcelOptionsT.parcel_id) {
|
||||
it[ParcelOptionsT.parcel_id] = id
|
||||
it[ParcelOptionsT.interact_inventory] = value
|
||||
}
|
||||
@@ -259,7 +256,7 @@ class ExposedBacking(private val dataSourceFactory: () -> DataSource) : Backing
|
||||
|
||||
override suspend fun setParcelAllowsInteractInputs(parcel: Parcel, value: Boolean): Unit = transaction {
|
||||
val id = getOrInitParcelId(parcel)
|
||||
ParcelOptionsT.insertOrUpdate(ParcelOptionsT.interact_inputs) {
|
||||
ParcelOptionsT.upsert(ParcelOptionsT.parcel_id) {
|
||||
it[ParcelOptionsT.parcel_id] = id
|
||||
it[ParcelOptionsT.interact_inputs] = value
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package io.dico.parcels2.storage
|
||||
|
||||
import org.jetbrains.exposed.sql.Column
|
||||
import org.jetbrains.exposed.sql.Table
|
||||
import org.jetbrains.exposed.sql.Transaction
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.statements.InsertStatement
|
||||
import org.jetbrains.exposed.sql.statements.UpdateStatement
|
||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||
|
||||
/*
|
||||
@@ -29,8 +28,82 @@ class InsertOrUpdate<Key : Any>(
|
||||
}
|
||||
|
||||
|
||||
class UpsertStatement<Key : Any>(table: Table, conflictColumn: Column<*>? = null, conflictIndex: Index? = null)
|
||||
: InsertStatement<Key>(table, false) {
|
||||
val indexName: String
|
||||
val indexColumns: List<Column<*>>
|
||||
|
||||
init {
|
||||
if (conflictIndex != null) {
|
||||
indexName = conflictIndex.indexName
|
||||
indexColumns = conflictIndex.columns
|
||||
} else if (conflictColumn != null) {
|
||||
indexName = conflictColumn.name
|
||||
indexColumns = listOf(conflictColumn)
|
||||
} else {
|
||||
throw IllegalArgumentException()
|
||||
}
|
||||
}
|
||||
|
||||
override fun prepareSQL(transaction: Transaction): String {
|
||||
val insertSQL = super.prepareSQL(transaction)
|
||||
val args = arguments!!.first()
|
||||
val map = mutableMapOf<Column<Any?>, Any?>().apply { args.forEach { put(it.first.castUnchecked(), it.second) } }
|
||||
|
||||
val updateSQL = updateBody(table, UpdateStatement(table, null, combineAsConjunctions(indexColumns.castUnchecked(), map))) {
|
||||
map.forEach { col, value ->
|
||||
if (col !in columns) {
|
||||
it[col] = value
|
||||
}
|
||||
}
|
||||
}.prepareSQL(transaction)
|
||||
|
||||
val builder = StringBuilder().apply {
|
||||
append(insertSQL)
|
||||
append(" ON CONFLICT(")
|
||||
append(indexName)
|
||||
append(") DO UPDATE ")
|
||||
append(updateSQL)
|
||||
}
|
||||
|
||||
return builder.toString().also { println(it) }
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
||||
inline fun <T : Table> updateBody(table: T, updateStatement: UpdateStatement,
|
||||
body: T.(UpdateStatement) -> Unit): UpdateStatement {
|
||||
table.body(updateStatement)
|
||||
return updateStatement
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST", "NOTHING_TO_INLINE")
|
||||
inline fun <T> Any.castUnchecked() = this as T
|
||||
|
||||
private val absent = Any() // marker object
|
||||
fun combineAsConjunctions(columns: Iterable<Column<Any?>>, map: Map<Column<Any?>, Any?>): Op<Boolean>? {
|
||||
return with(SqlExpressionBuilder) {
|
||||
columns.fold<Column<Any?>, Op<Boolean>?>(null) { op, col ->
|
||||
val arg = map.getOrDefault(col, absent)
|
||||
if (arg === absent) return@fold op
|
||||
op?.let { it and (col eq arg) } ?: col eq arg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <T : Table> T.upsert(conflictColumn: Column<*>? = null, conflictIndex: Index? = null, body: T.(UpsertStatement<Number>) -> Unit) =
|
||||
UpsertStatement<Number>(this, conflictColumn, conflictIndex).apply {
|
||||
body(this)
|
||||
execute(TransactionManager.current())
|
||||
}
|
||||
|
||||
fun Table.indexR(customIndexName:String? = null, isUnique: Boolean = false, vararg columns: Column<*>): Index {
|
||||
val index = Index(columns.toList(), isUnique, customIndexName)
|
||||
indices.add(index)
|
||||
return index
|
||||
}
|
||||
|
||||
fun Table.uniqueIndexR(customIndexName:String? = null, vararg columns: Column<*>): Index = indexR(customIndexName, true, *columns)
|
||||
|
||||
Reference in New Issue
Block a user