summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDico Karssiens <dico.karssiens@gmail.com>2018-07-29 01:03:31 +0100
committerDico Karssiens <dico.karssiens@gmail.com>2018-07-29 01:03:31 +0100
commitd425a1e977cb03a7b9162e3dcb775cabeff52814 (patch)
treef0bcc94a0912c8a79fbcb7c30c389542402311b6
parent547ffcb0ba8407838e0ec9241406206b38885ad2 (diff)
Tweaks and fixes
-rw-r--r--build.gradle.kts203
-rw-r--r--dicore3/command/build.gradle.kts3
-rw-r--r--dicore3/command/src/main/java/io/dico/dicore/command/Command.java12
-rw-r--r--dicore3/command/src/main/java/io/dico/dicore/command/CommandBuilder.java9
-rw-r--r--dicore3/command/src/main/java/io/dico/dicore/command/parameter/Parameter.java21
-rw-r--r--dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/NumberParameterType.java3
-rw-r--r--dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterKey.java57
-rw-r--r--dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterTypes.java7
-rw-r--r--dicore3/command/src/main/java/io/dico/dicore/command/predef/HelpCommandExtended.java7
-rw-r--r--dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveRegistration.java5
-rw-r--r--dicore3/command/src/main/kotlin/io/dico/dicore/command/registration/reflect/KotlinReflectiveRegistration.kt7
-rw-r--r--dicore3/core/build.gradle.kts12
-rw-r--r--old-build.gradle.kts206
-rw-r--r--src/main/kotlin/io/dico/parcels2/ParcelWorld.kt23
-rw-r--r--src/main/kotlin/io/dico/parcels2/WorldGenerator.kt2
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/CommandsParcelOptions.kt1
-rw-r--r--src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt27
-rw-r--r--src/main/kotlin/io/dico/parcels2/storage/ExposedBacking.kt29
-rw-r--r--src/main/kotlin/io/dico/parcels2/storage/ExposedExtensions.kt79
19 files changed, 507 insertions, 206 deletions
diff --git a/build.gradle.kts b/build.gradle.kts
index d358fcc..a1a6e4f 100644
--- a/build.gradle.kts
+++ b/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",
-
- "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)
- }
+ /*
+ Shadow Jar is retarded so it also relocates packages not included in the releaseJar (such as the bukkit api)
-}
+ relocate("", "io.dico.parcels2.lib.") {
+ exclude("*yml")
+ exclude("*xml")
+ exclude("META-INF/*")
+ exclude("io/dico/*")
+ }
+ */*/*/
-allprojects {
- tasks.filter { it is Jar }.forEach { it.group = "artifacts" }
+ // 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.")
+
+ manifest.attributes["Class-Path"] = "../lib/kotlin-stdlib.jar"
+ dependsOn(kotlinStdlibJar)
+ }
}
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()) }
diff --git a/dicore3/command/build.gradle.kts b/dicore3/command/build.gradle.kts
index b4e64bd..6bc75ec 100644
--- a/dicore3/command/build.gradle.kts
+++ b/dicore3/command/build.gradle.kts
@@ -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"
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/Command.java b/dicore3/command/src/main/java/io/dico/dicore/command/Command.java
index 0ba04b1..b66b5f5 100644
--- a/dicore3/command/src/main/java/io/dico/dicore/command/Command.java
+++ b/dicore3/command/src/main/java/io/dico/dicore/command/Command.java
@@ -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) {
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/CommandBuilder.java b/dicore3/command/src/main/java/io/dico/dicore/command/CommandBuilder.java
index 59eebf9..0ffc960 100644
--- a/dicore3/command/src/main/java/io/dico/dicore/command/CommandBuilder.java
+++ b/dicore3/command/src/main/java/io/dico/dicore/command/CommandBuilder.java
@@ -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;
}
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/Parameter.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/Parameter.java
index ca66068..9ce1119 100644
--- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/Parameter.java
+++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/Parameter.java
@@ -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;
}
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/NumberParameterType.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/NumberParameterType.java
index ed53cb0..4aac122 100644
--- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/NumberParameterType.java
+++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/NumberParameterType.java
@@ -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);
}
}
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterKey.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterKey.java
index 67f86d4..ee265e6 100644
--- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterKey.java
+++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterKey.java
@@ -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);
+ }
+
}
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterTypes.java b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterTypes.java
index 98b7b77..678bbc6 100644
--- a/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterTypes.java
+++ b/dicore3/command/src/main/java/io/dico/dicore/command/parameter/type/ParameterTypes.java
@@ -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
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/predef/HelpCommandExtended.java b/dicore3/command/src/main/java/io/dico/dicore/command/predef/HelpCommandExtended.java
new file mode 100644
index 0000000..49f5e72
--- /dev/null
+++ b/dicore3/command/src/main/java/io/dico/dicore/command/predef/HelpCommandExtended.java
@@ -0,0 +1,7 @@
+package io.dico.dicore.command.predef;
+
+public class HelpCommandExtended {
+
+ // TODO
+
+}
diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveRegistration.java b/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveRegistration.java
index 0003c1f..669f440 100644
--- a/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveRegistration.java
+++ b/dicore3/command/src/main/java/io/dico/dicore/command/registration/reflect/ReflectiveRegistration.java
@@ -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);
}
diff --git a/dicore3/command/src/main/kotlin/io/dico/dicore/command/registration/reflect/KotlinReflectiveRegistration.kt b/dicore3/command/src/main/kotlin/io/dico/dicore/command/registration/reflect/KotlinReflectiveRegistration.kt
index bc48a26..9d23ee6 100644
--- a/dicore3/command/src/main/kotlin/io/dico/dicore/command/registration/reflect/KotlinReflectiveRegistration.kt
+++ b/dicore3/command/src/main/kotlin/io/dico/dicore/command/registration/reflect/KotlinReflectiveRegistration.kt
@@ -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
} \ No newline at end of file
diff --git a/dicore3/core/build.gradle.kts b/dicore3/core/build.gradle.kts
index 3fa41d2..76a7382 100644
--- a/dicore3/core/build.gradle.kts
+++ b/dicore3/core/build.gradle.kts
@@ -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"))
-
-} \ No newline at end of file
diff --git a/old-build.gradle.kts b/old-build.gradle.kts
new file mode 100644
index 0000000..fa79c4d
--- /dev/null
+++ b/old-build.gradle.kts
@@ -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())
+ }
+}
diff --git a/src/main/kotlin/io/dico/parcels2/ParcelWorld.kt b/src/main/kotlin/io/dico/parcels2/ParcelWorld.kt
index a2e8155..d4287af 100644
--- a/src/main/kotlin/io/dico/parcels2/ParcelWorld.kt
+++ b/src/main/kotlin/io/dico/parcels2/ParcelWorld.kt
@@ -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 {
diff --git a/src/main/kotlin/io/dico/parcels2/WorldGenerator.kt b/src/main/kotlin/io/dico/parcels2/WorldGenerator.kt
index 15fbde6..6bd214b 100644
--- a/src/main/kotlin/io/dico/parcels2/WorldGenerator.kt
+++ b/src/main/kotlin/io/dico/parcels2/WorldGenerator.kt
@@ -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
diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsParcelOptions.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsParcelOptions.kt
index 7f900d5..c77686e 100644
--- a/src/main/kotlin/io/dico/parcels2/command/CommandsParcelOptions.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/CommandsParcelOptions.kt
@@ -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")
}
diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
index 284c6d4..2ba16e2 100644
--- a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
+++ b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt
@@ -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)
+ }
+ }
+}
diff --git a/src/main/kotlin/io/dico/parcels2/storage/ExposedBacking.kt b/src/main/kotlin/io/dico/parcels2/storage/ExposedBacking.kt
index a78cab8..fc0591c 100644
--- a/src/main/kotlin/io/dico/parcels2/storage/ExposedBacking.kt
+++ b/src/main/kotlin/io/dico/parcels2/storage/ExposedBacking.kt
@@ -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
}
diff --git a/src/main/kotlin/io/dico/parcels2/storage/ExposedExtensions.kt b/src/main/kotlin/io/dico/parcels2/storage/ExposedExtensions.kt
index d4aee11..bb6133d 100644
--- a/src/main/kotlin/io/dico/parcels2/storage/ExposedExtensions.kt
+++ b/src/main/kotlin/io/dico/parcels2/storage/ExposedExtensions.kt
@@ -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)