new-1.1
This commit is contained in:
parent
706de6f042
commit
c6b53cb30b
35
pom.xml
35
pom.xml
|
@ -81,14 +81,13 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.papermc.paper</groupId>
|
<groupId>io.papermc.paper</groupId>
|
||||||
<artifactId>paper-api</artifactId>
|
<artifactId>paper-api</artifactId>
|
||||||
<version>1.20.4-R0.1-SNAPSHOT</version>
|
<version>1.20.6-R0.1-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
<groupId>io.papermc.paper</groupId>
|
||||||
<artifactId>spigot</artifactId>
|
<artifactId>paper-nms</artifactId>
|
||||||
<version>1.20.4</version>
|
<version>1.20.6</version>
|
||||||
<classifier>nms</classifier>
|
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -112,34 +111,24 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-compress</artifactId>
|
<artifactId>commons-compress</artifactId>
|
||||||
<version>1.26.2</version>
|
<version>1.27.1</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>2.18.2</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.luben</groupId>
|
<groupId>com.github.luben</groupId>
|
||||||
<artifactId>zstd-jni</artifactId>
|
<artifactId>zstd-jni</artifactId>
|
||||||
<version>1.5.6-3</version>
|
<version>1.5.6-9</version>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.zaxxer</groupId>
|
|
||||||
<artifactId>HikariCP</artifactId>
|
|
||||||
<version>4.0.3</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.xerial</groupId>
|
|
||||||
<artifactId>sqlite-jdbc</artifactId>
|
|
||||||
<version>3.46.0.0</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
|
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>redis.clients</groupId>
|
<groupId>redis.clients</groupId>
|
||||||
<artifactId>jedis</artifactId>
|
<artifactId>jedis</artifactId>
|
||||||
<version>5.1.3</version>
|
<version>5.2.0</version>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -9,7 +9,6 @@ import net.byteflux.libby.*;
|
||||||
import net.byteflux.libby.logging.LogLevel;
|
import net.byteflux.libby.logging.LogLevel;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import redis.clients.jedis.Jedis;
|
|
||||||
|
|
||||||
public final class ElementOriginLib extends JavaPlugin {
|
public final class ElementOriginLib extends JavaPlugin {
|
||||||
|
|
||||||
|
@ -18,19 +17,25 @@ public final class ElementOriginLib extends JavaPlugin {
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(ElementOriginLib.class);
|
private static Logger logger = Logger.getLogger(ElementOriginLib.class);
|
||||||
|
|
||||||
|
private static RedisIO redisIO;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
instance = this;
|
instance = this;
|
||||||
|
|
||||||
loadLibraries();
|
loadLibraries();
|
||||||
|
|
||||||
Lang.registerLangFile(this);
|
|
||||||
Lang.reload();
|
|
||||||
|
|
||||||
new GuiHandlerListener(this);
|
new GuiHandlerListener(this);
|
||||||
new PlayerChatInputListener(this);
|
new PlayerChatInputListener(this);
|
||||||
|
|
||||||
|
Lang.registerLangFile(this);
|
||||||
|
Lang.reload();
|
||||||
|
|
||||||
|
redisIO = new RedisIO();
|
||||||
|
redisIO.init(this);
|
||||||
|
|
||||||
logger.info("Successfully load ElementOriginLib v"+getPluginMeta().getVersion());
|
logger.info("Successfully load ElementOriginLib v"+getPluginMeta().getVersion());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadLibraries() {
|
private void loadLibraries() {
|
||||||
|
@ -38,11 +43,11 @@ public final class ElementOriginLib extends JavaPlugin {
|
||||||
LibraryManager libraryManager = new BukkitLibraryManager(this);
|
LibraryManager libraryManager = new BukkitLibraryManager(this);
|
||||||
libraryManager.addMavenCentral();
|
libraryManager.addMavenCentral();
|
||||||
libraryManager.setLogLevel(LogLevel.WARN);
|
libraryManager.setLogLevel(LogLevel.WARN);
|
||||||
libraryManager.loadLibrary(Library.builder().groupId("org{}apache{}commons").artifactId("commons-compress").version("1.26.2").build());
|
libraryManager.loadLibrary(Library.builder().groupId("org{}apache{}commons").artifactId("commons-compress").version("1.27.1").build());
|
||||||
libraryManager.loadLibrary(Library.builder().groupId("com{}github{}luben").artifactId("zstd-jni").version("1.5.6-3").build());
|
// libraryManager.loadLibrary(Library.builder().groupId("com{}github{}luben").artifactId("zstd-jni").version("1.5.6-9").build());
|
||||||
libraryManager.loadLibrary(Library.builder().groupId("com{}zaxxer").artifactId("HikariCP").version("4.0.3").build());
|
// libraryManager.loadLibrary(Library.builder().groupId("com{}zaxxer").artifactId("HikariCP").version("6.2.1").build());
|
||||||
libraryManager.loadLibrary(Library.builder().groupId("org{}xerial").artifactId("sqlite-jdbc").version("3.46.0.0").build());
|
// libraryManager.loadLibrary(Library.builder().groupId("org{}xerial").artifactId("sqlite-jdbc").version("3.46.0.0").build());
|
||||||
libraryManager.loadLibrary(Library.builder().groupId("redis{}clients").id("jedis").artifactId("jedis").version("5.1.3").build());
|
// libraryManager.loadLibrary(Library.builder().groupId("redis{}clients").id("jedis").artifactId("jedis").version("5.2.0").build());
|
||||||
logger.info("Successfully loaded libraries.");
|
logger.info("Successfully loaded libraries.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +55,10 @@ public final class ElementOriginLib extends JavaPlugin {
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static RedisIO getRedisIO() {
|
||||||
|
return redisIO;
|
||||||
|
}
|
||||||
|
|
||||||
public static ElementOriginLib inst() {
|
public static ElementOriginLib inst() {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.io.yutian.elementoriginlib.datasync;
|
||||||
|
|
||||||
|
import com.io.yutian.elementoriginlib.ElementOriginLib;
|
||||||
|
import com.io.yutian.elementoriginlib.serialize.SerializeHelper;
|
||||||
|
import redis.clients.jedis.Jedis;
|
||||||
|
|
||||||
|
public class DataSyncHelper {
|
||||||
|
|
||||||
|
public static void saveData(String key, Object value) {
|
||||||
|
String strValue = SerializeHelper.serialize(value);
|
||||||
|
try (Jedis jedis = ElementOriginLib.getRedisIO().getJedisPool().getResource()) {
|
||||||
|
jedis.set(key, strValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T getData(String key, Class<T> clazz) {
|
||||||
|
try (Jedis jedis = ElementOriginLib.getRedisIO().getJedisPool().getResource()) {
|
||||||
|
if (!jedis.exists(key)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String strValue = jedis.get(key);
|
||||||
|
if (strValue == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return SerializeHelper.deserialize(strValue, clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package com.io.yutian.elementoriginlib.gui.button;
|
package com.io.yutian.elementoriginlib.gui.button;
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.nbt.NBTItem;
|
import com.io.yutian.elementoriginlib.nbt.NBTItem;
|
||||||
import com.io.yutian.elementoriginlib.nbt.NBTString;
|
import com.io.yutian.elementoriginlib.nbt.TagString;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ public class ItemButton extends Button {
|
||||||
|
|
||||||
public boolean isItem(ItemStack item) {
|
public boolean isItem(ItemStack item) {
|
||||||
NBTItem nbtItem = new NBTItem(item);
|
NBTItem nbtItem = new NBTItem(item);
|
||||||
return nbtItem.has("gui_meta", NBTString.TYPE_ID) && ((NBTString) nbtItem.get("gui_meta")).getString().equals("item_button");
|
return nbtItem.has("gui_meta", TagString.TYPE_ID) && ((TagString) nbtItem.get("gui_meta")).getString().equals("item_button");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemButton clickItem(BiConsumer<Player, ItemStack> consumer) {
|
public ItemButton clickItem(BiConsumer<Player, ItemStack> consumer) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.io.yutian.elementoriginlib.item.stat.type;
|
||||||
import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder;
|
import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder;
|
||||||
import com.io.yutian.elementoriginlib.item.stat.ItemStat;
|
import com.io.yutian.elementoriginlib.item.stat.ItemStat;
|
||||||
import com.io.yutian.elementoriginlib.item.stat.data.BooleanData;
|
import com.io.yutian.elementoriginlib.item.stat.data.BooleanData;
|
||||||
import com.io.yutian.elementoriginlib.nbt.NBTByte;
|
import com.io.yutian.elementoriginlib.nbt.TagByte;
|
||||||
import com.io.yutian.elementoriginlib.nbt.NBTItem;
|
import com.io.yutian.elementoriginlib.nbt.NBTItem;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
@ -23,7 +23,7 @@ public abstract class BooleanStat extends ItemStat<BooleanData> {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public BooleanData getLoadedNBT(@NotNull NBTItem nbtItem) {
|
public BooleanData getLoadedNBT(@NotNull NBTItem nbtItem) {
|
||||||
return new BooleanData(((NBTByte) nbtItem.get(getNBTPath())).getByte() == 1);
|
return new BooleanData(((TagByte) nbtItem.get(getNBTPath())).getByte() == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.io.yutian.elementoriginlib.item.stat.type;
|
||||||
import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder;
|
import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder;
|
||||||
import com.io.yutian.elementoriginlib.item.stat.ItemStat;
|
import com.io.yutian.elementoriginlib.item.stat.ItemStat;
|
||||||
import com.io.yutian.elementoriginlib.item.stat.data.DoubleData;
|
import com.io.yutian.elementoriginlib.item.stat.data.DoubleData;
|
||||||
import com.io.yutian.elementoriginlib.nbt.NBTDouble;
|
import com.io.yutian.elementoriginlib.nbt.TagDouble;
|
||||||
import com.io.yutian.elementoriginlib.nbt.NBTItem;
|
import com.io.yutian.elementoriginlib.nbt.NBTItem;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
@ -23,7 +23,7 @@ public abstract class DoubleStat extends ItemStat<DoubleData> {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public DoubleData getLoadedNBT(@NotNull NBTItem nbtItem) {
|
public DoubleData getLoadedNBT(@NotNull NBTItem nbtItem) {
|
||||||
return new DoubleData(((NBTDouble) nbtItem.get(getNBTPath())).getDouble());
|
return new DoubleData(((TagDouble) nbtItem.get(getNBTPath())).getDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.io.yutian.elementoriginlib.item.stat.type;
|
||||||
import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder;
|
import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder;
|
||||||
import com.io.yutian.elementoriginlib.item.stat.ItemStat;
|
import com.io.yutian.elementoriginlib.item.stat.ItemStat;
|
||||||
import com.io.yutian.elementoriginlib.item.stat.data.IntData;
|
import com.io.yutian.elementoriginlib.item.stat.data.IntData;
|
||||||
import com.io.yutian.elementoriginlib.nbt.NBTInt;
|
import com.io.yutian.elementoriginlib.nbt.TagInt;
|
||||||
import com.io.yutian.elementoriginlib.nbt.NBTItem;
|
import com.io.yutian.elementoriginlib.nbt.NBTItem;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
@ -23,7 +23,7 @@ public abstract class IntStat extends ItemStat<IntData> {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public IntData getLoadedNBT(@NotNull NBTItem nbtItem) {
|
public IntData getLoadedNBT(@NotNull NBTItem nbtItem) {
|
||||||
return new IntData(((NBTInt)nbtItem.get(getNBTPath())).getInt());
|
return new IntData(((TagInt)nbtItem.get(getNBTPath())).getInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@ import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder;
|
||||||
import com.io.yutian.elementoriginlib.item.stat.ItemStat;
|
import com.io.yutian.elementoriginlib.item.stat.ItemStat;
|
||||||
import com.io.yutian.elementoriginlib.item.stat.data.StringListData;
|
import com.io.yutian.elementoriginlib.item.stat.data.StringListData;
|
||||||
import com.io.yutian.elementoriginlib.nbt.NBTItem;
|
import com.io.yutian.elementoriginlib.nbt.NBTItem;
|
||||||
import com.io.yutian.elementoriginlib.nbt.NBTList;
|
import com.io.yutian.elementoriginlib.nbt.TagList;
|
||||||
import com.io.yutian.elementoriginlib.nbt.NBTString;
|
import com.io.yutian.elementoriginlib.nbt.TagString;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
@ -21,21 +21,21 @@ public abstract class StringListStat extends ItemStat<StringListData> {
|
||||||
@Override
|
@Override
|
||||||
public void whenApplied(@NotNull OriginItemStackBuilder itemStackBuilder, @NotNull StringListData statData) {
|
public void whenApplied(@NotNull OriginItemStackBuilder itemStackBuilder, @NotNull StringListData statData) {
|
||||||
NBTItem nbtItem = itemStackBuilder.getNBTItem();
|
NBTItem nbtItem = itemStackBuilder.getNBTItem();
|
||||||
NBTList<NBTString> nbtList = new NBTList<>();
|
TagList<TagString> tagList = new TagList<>();
|
||||||
statData.getList().forEach(s -> nbtList.add(new NBTString(s)));
|
statData.getList().forEach(s -> tagList.add(new TagString(s)));
|
||||||
nbtItem.editTag(nbtCompound -> nbtCompound.put(getNBTPath(), nbtList));
|
nbtItem.editTag(nbtCompound -> nbtCompound.put(getNBTPath(), tagList));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public StringListData getLoadedNBT(@NotNull NBTItem nbtItem) {
|
public StringListData getLoadedNBT(@NotNull NBTItem nbtItem) {
|
||||||
if (!nbtItem.has(getNBTPath(), NBTList.TYPE_ID)) {
|
if (!nbtItem.has(getNBTPath(), TagList.TYPE_ID)) {
|
||||||
return new StringListData(new ArrayList<>());
|
return new StringListData(new ArrayList<>());
|
||||||
}
|
}
|
||||||
NBTList<NBTString> nbtList = (NBTList<NBTString>) nbtItem.get(getNBTPath());
|
TagList<TagString> tagList = (TagList<TagString>) nbtItem.get(getNBTPath());
|
||||||
List<String> list = new ArrayList<>();
|
List<String> list = new ArrayList<>();
|
||||||
for (int i = 0; i < nbtList.size(); i++) {
|
for (int i = 0; i < tagList.size(); i++) {
|
||||||
list.add(nbtList.get(i).getString());
|
list.add(tagList.get(i).getString());
|
||||||
}
|
}
|
||||||
return new StringListData(list);
|
return new StringListData(list);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder;
|
||||||
import com.io.yutian.elementoriginlib.item.stat.ItemStat;
|
import com.io.yutian.elementoriginlib.item.stat.ItemStat;
|
||||||
import com.io.yutian.elementoriginlib.item.stat.data.StringData;
|
import com.io.yutian.elementoriginlib.item.stat.data.StringData;
|
||||||
import com.io.yutian.elementoriginlib.nbt.NBTItem;
|
import com.io.yutian.elementoriginlib.nbt.NBTItem;
|
||||||
import com.io.yutian.elementoriginlib.nbt.NBTString;
|
import com.io.yutian.elementoriginlib.nbt.TagString;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ public abstract class StringStat extends ItemStat<StringData> {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public StringData getLoadedNBT(@NotNull NBTItem nbtItem) {
|
public StringData getLoadedNBT(@NotNull NBTItem nbtItem) {
|
||||||
return new StringData(((NBTString) nbtItem.get(getNBTPath())).getString());
|
return new StringData(((TagString) nbtItem.get(getNBTPath())).getString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder;
|
||||||
import com.io.yutian.elementoriginlib.item.stat.ItemStat;
|
import com.io.yutian.elementoriginlib.item.stat.ItemStat;
|
||||||
import com.io.yutian.elementoriginlib.item.stat.data.UUIDData;
|
import com.io.yutian.elementoriginlib.item.stat.data.UUIDData;
|
||||||
import com.io.yutian.elementoriginlib.nbt.NBTItem;
|
import com.io.yutian.elementoriginlib.nbt.NBTItem;
|
||||||
import com.io.yutian.elementoriginlib.nbt.NBTString;
|
import com.io.yutian.elementoriginlib.nbt.TagString;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ public abstract class UUIDStat extends ItemStat<UUIDData> {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public UUIDData getLoadedNBT(@NotNull NBTItem nbtItem) {
|
public UUIDData getLoadedNBT(@NotNull NBTItem nbtItem) {
|
||||||
return new UUIDData(UUID.fromString(((NBTString) nbtItem.get(getNBTPath())).getString()));
|
return new UUIDData(UUID.fromString(((TagString) nbtItem.get(getNBTPath())).getString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,180 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.nbt;
|
|
||||||
|
|
||||||
import net.minecraft.nbt.*;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public interface INBT {
|
|
||||||
|
|
||||||
Object getValue();
|
|
||||||
|
|
||||||
byte getTypeId();
|
|
||||||
|
|
||||||
private static String getNBTTag(byte typeByte) {
|
|
||||||
return switch (typeByte) {
|
|
||||||
case 1 -> "NBTTagByte";
|
|
||||||
case 2 -> "NBTTagShort";
|
|
||||||
case 3 -> "NBTTagInt";
|
|
||||||
case 4 -> "NBTTagLong";
|
|
||||||
case 5 -> "NBTTagFloat";
|
|
||||||
case 6 -> "NBTTagDouble";
|
|
||||||
case 7 -> "NBTTagByteArray";
|
|
||||||
case 8 -> "NBTTagString";
|
|
||||||
case 9 -> "NBTTagList";
|
|
||||||
case 10 -> "NBTTagCompound";
|
|
||||||
case 11 -> "NBTTagIntArray";
|
|
||||||
case 12 -> "NBTTagLongArray";
|
|
||||||
default -> null;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static INBT asObject(Object object) {
|
|
||||||
if (object instanceof Byte b) {
|
|
||||||
return new NBTByte(b);
|
|
||||||
} else if (object instanceof Short value) {
|
|
||||||
return new NBTShort(value);
|
|
||||||
} else if (object instanceof Integer value) {
|
|
||||||
return new NBTInt(value);
|
|
||||||
} else if (object instanceof Long value) {
|
|
||||||
return new NBTLong(value);
|
|
||||||
} else if (object instanceof Float value) {
|
|
||||||
return new NBTFloat(value);
|
|
||||||
} else if (object instanceof Double value) {
|
|
||||||
return new NBTDouble(value);
|
|
||||||
} else if (object instanceof byte[] value) {
|
|
||||||
return new NBTByteArray(value);
|
|
||||||
} else if (object instanceof String value) {
|
|
||||||
return new NBTString(value);
|
|
||||||
} else if (object instanceof int[] value) {
|
|
||||||
return new NBTIntArray(value);
|
|
||||||
} else if (object instanceof long[] value) {
|
|
||||||
return new NBTLongArray(value);
|
|
||||||
} else if (object instanceof Boolean b) {
|
|
||||||
return new NBTByte((byte) (b ? 1 : 0));
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static net.minecraft.nbt.NBTBase asNMS(INBT nbt) {
|
|
||||||
byte type = nbt.getTypeId();
|
|
||||||
switch (type) {
|
|
||||||
case 1 -> {
|
|
||||||
NBTByte nbtByte = (NBTByte) nbt;
|
|
||||||
return NBTTagByte.a(nbtByte.getByte());
|
|
||||||
}
|
|
||||||
case 2 -> {
|
|
||||||
NBTShort nbtShort = (NBTShort) nbt;
|
|
||||||
return NBTTagShort.a(nbtShort.getShort());
|
|
||||||
}
|
|
||||||
case 3 -> {
|
|
||||||
NBTInt nbtInt = (NBTInt) nbt;
|
|
||||||
return NBTTagInt.a(nbtInt.getInt());
|
|
||||||
}
|
|
||||||
case 4 -> {
|
|
||||||
NBTLong nbtLong = (NBTLong) nbt;
|
|
||||||
return NBTTagLong.a(nbtLong.getLong());
|
|
||||||
}
|
|
||||||
case 5 -> {
|
|
||||||
NBTFloat nbtfloat = (NBTFloat) nbt;
|
|
||||||
return NBTTagFloat.a(nbtfloat.getFloat());
|
|
||||||
}
|
|
||||||
case 6 -> {
|
|
||||||
NBTDouble nbtDouble = (NBTDouble) nbt;
|
|
||||||
return NBTTagDouble.a(nbtDouble.getDouble());
|
|
||||||
}
|
|
||||||
case 7 -> {
|
|
||||||
NBTByteArray nbtByteArray = (NBTByteArray) nbt;
|
|
||||||
return new NBTTagByteArray(nbtByteArray.getByteArray());
|
|
||||||
}
|
|
||||||
case 8 -> {
|
|
||||||
NBTString nbtString = (NBTString) nbt;
|
|
||||||
return NBTTagString.a(nbtString.getString());
|
|
||||||
}
|
|
||||||
case 9 -> {
|
|
||||||
NBTList nbtTagList = (NBTList) nbt;
|
|
||||||
List<net.minecraft.nbt.NBTBase> list = new ArrayList<>();
|
|
||||||
for (Object base : nbtTagList.getList()) {
|
|
||||||
list.add(asNMS((INBT) base));
|
|
||||||
}
|
|
||||||
NBTTagList nbtTagList1 = new NBTTagList();
|
|
||||||
for (net.minecraft.nbt.NBTBase nbt1 : list) {
|
|
||||||
nbtTagList1.add(nbt1);
|
|
||||||
}
|
|
||||||
return nbtTagList1;
|
|
||||||
}
|
|
||||||
case 10 -> {
|
|
||||||
NBTCompound nbtCompound = (NBTCompound) nbt;
|
|
||||||
NBTTagCompound nbtTagCompound = new NBTTagCompound();
|
|
||||||
for (String key : nbtCompound.keySet()) {
|
|
||||||
INBT nbt1 = nbtCompound.get(key);
|
|
||||||
nbtTagCompound.a(key, asNMS(nbt1));
|
|
||||||
}
|
|
||||||
return nbtTagCompound;
|
|
||||||
}
|
|
||||||
case 11 -> {
|
|
||||||
NBTIntArray nbtIntArray = (NBTIntArray) nbt;
|
|
||||||
return new NBTTagIntArray(nbtIntArray.getIntArray());
|
|
||||||
}
|
|
||||||
case 12 -> {
|
|
||||||
NBTLongArray nbtLongArray = (NBTLongArray) nbt;
|
|
||||||
return new NBTTagLongArray(nbtLongArray.getLongArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INBT as(net.minecraft.nbt.NBTBase nbtBase) {
|
|
||||||
byte type = nbtBase.b();
|
|
||||||
switch (type) {
|
|
||||||
case 1:
|
|
||||||
NBTTagByte nbtTagByte = (NBTTagByte) nbtBase;
|
|
||||||
return new NBTByte(nbtTagByte.i());
|
|
||||||
case 2:
|
|
||||||
NBTTagShort nbtTagShort = (NBTTagShort) nbtBase;
|
|
||||||
return new NBTShort(nbtTagShort.h());
|
|
||||||
case 3:
|
|
||||||
NBTTagInt nbtTagInt = (NBTTagInt) nbtBase;
|
|
||||||
return new NBTInt(nbtTagInt.g());
|
|
||||||
case 4:
|
|
||||||
NBTTagLong nbtTagLong = (NBTTagLong) nbtBase;
|
|
||||||
return new NBTLong(nbtTagLong.f());
|
|
||||||
case 5:
|
|
||||||
NBTTagFloat nbtTagFloat = (NBTTagFloat) nbtBase;
|
|
||||||
return new NBTFloat(nbtTagFloat.k());
|
|
||||||
case 6:
|
|
||||||
NBTTagDouble nbtTagDouble = (NBTTagDouble) nbtBase;
|
|
||||||
return new NBTDouble(nbtTagDouble.j());
|
|
||||||
case 7:
|
|
||||||
NBTTagByteArray tagByteArray = (NBTTagByteArray) nbtBase;
|
|
||||||
return new NBTByteArray(tagByteArray.e());
|
|
||||||
case 8:
|
|
||||||
NBTTagString nbtTagString = (NBTTagString) nbtBase;
|
|
||||||
return new NBTString(nbtTagString.t_());
|
|
||||||
case 9:
|
|
||||||
NBTTagList nbtTagList = (NBTTagList) nbtBase;
|
|
||||||
List<INBT> list = new ArrayList<>();
|
|
||||||
for (net.minecraft.nbt.NBTBase base : nbtTagList) {
|
|
||||||
list.add(as(base));
|
|
||||||
}
|
|
||||||
return new NBTList(list);
|
|
||||||
case 10:
|
|
||||||
NBTTagCompound nbtTagCompound = (NBTTagCompound) nbtBase;
|
|
||||||
Map<String, INBT> map = new HashMap<>();
|
|
||||||
for (String key : nbtTagCompound.e()) {
|
|
||||||
map.put(key, as(nbtTagCompound.c(key)));
|
|
||||||
}
|
|
||||||
return new NBTCompound(map);
|
|
||||||
case 11:
|
|
||||||
NBTTagIntArray nbtTagIntArray = (NBTTagIntArray) nbtBase;
|
|
||||||
return new NBTIntArray(nbtTagIntArray.g());
|
|
||||||
case 12:
|
|
||||||
NBTTagLongArray nbtTagLongArray = (NBTTagLongArray) nbtBase;
|
|
||||||
return new NBTLongArray(nbtTagLongArray.g());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
180
src/main/java/com/io/yutian/elementoriginlib/nbt/ITag.java
Normal file
180
src/main/java/com/io/yutian/elementoriginlib/nbt/ITag.java
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
package com.io.yutian.elementoriginlib.nbt;
|
||||||
|
|
||||||
|
import net.minecraft.nbt.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface ITag {
|
||||||
|
|
||||||
|
Object getValue();
|
||||||
|
|
||||||
|
byte getTypeId();
|
||||||
|
|
||||||
|
private static String getTag(byte typeByte) {
|
||||||
|
return switch (typeByte) {
|
||||||
|
case 1 -> "TagByte";
|
||||||
|
case 2 -> "TagShort";
|
||||||
|
case 3 -> "TagInt";
|
||||||
|
case 4 -> "TagLong";
|
||||||
|
case 5 -> "TagFloat";
|
||||||
|
case 6 -> "TagDouble";
|
||||||
|
case 7 -> "TagByteArray";
|
||||||
|
case 8 -> "TagString";
|
||||||
|
case 9 -> "TagList";
|
||||||
|
case 10 -> "TagCompound";
|
||||||
|
case 11 -> "TagIntArray";
|
||||||
|
case 12 -> "TagLongArray";
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static ITag asObject(Object object) {
|
||||||
|
if (object instanceof Byte b) {
|
||||||
|
return new TagByte(b);
|
||||||
|
} else if (object instanceof Short value) {
|
||||||
|
return new TagShort(value);
|
||||||
|
} else if (object instanceof Integer value) {
|
||||||
|
return new TagInt(value);
|
||||||
|
} else if (object instanceof Long value) {
|
||||||
|
return new TagLong(value);
|
||||||
|
} else if (object instanceof Float value) {
|
||||||
|
return new TagFloat(value);
|
||||||
|
} else if (object instanceof Double value) {
|
||||||
|
return new TagDouble(value);
|
||||||
|
} else if (object instanceof byte[] value) {
|
||||||
|
return new TagByteArray(value);
|
||||||
|
} else if (object instanceof String value) {
|
||||||
|
return new TagString(value);
|
||||||
|
} else if (object instanceof int[] value) {
|
||||||
|
return new TagIntArray(value);
|
||||||
|
} else if (object instanceof long[] value) {
|
||||||
|
return new TagLongArray(value);
|
||||||
|
} else if (object instanceof Boolean b) {
|
||||||
|
return new TagByte((byte) (b ? 1 : 0));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static net.minecraft.nbt.Tag asNMS(ITag nbt) {
|
||||||
|
byte type = nbt.getTypeId();
|
||||||
|
switch (type) {
|
||||||
|
case 1 -> {
|
||||||
|
TagByte tagByte = (TagByte) nbt;
|
||||||
|
return ByteTag.valueOf(tagByte.getByte());
|
||||||
|
}
|
||||||
|
case 2 -> {
|
||||||
|
TagShort nbtShort = (TagShort) nbt;
|
||||||
|
return ShortTag.valueOf(nbtShort.getShort());
|
||||||
|
}
|
||||||
|
case 3 -> {
|
||||||
|
TagInt tagInt = (TagInt) nbt;
|
||||||
|
return IntTag.valueOf(tagInt.getInt());
|
||||||
|
}
|
||||||
|
case 4 -> {
|
||||||
|
TagLong tagLong = (TagLong) nbt;
|
||||||
|
return LongTag.valueOf(tagLong.getLong());
|
||||||
|
}
|
||||||
|
case 5 -> {
|
||||||
|
TagFloat nbtfloat = (TagFloat) nbt;
|
||||||
|
return FloatTag.valueOf(nbtfloat.getFloat());
|
||||||
|
}
|
||||||
|
case 6 -> {
|
||||||
|
TagDouble tagDouble = (TagDouble) nbt;
|
||||||
|
return DoubleTag.valueOf(tagDouble.getDouble());
|
||||||
|
}
|
||||||
|
case 7 -> {
|
||||||
|
TagByteArray tagByteArray = (TagByteArray) nbt;
|
||||||
|
return new ByteArrayTag(tagByteArray.getByteArray());
|
||||||
|
}
|
||||||
|
case 8 -> {
|
||||||
|
TagString tagString = (TagString) nbt;
|
||||||
|
return StringTag.valueOf(tagString.getString());
|
||||||
|
}
|
||||||
|
case 9 -> {
|
||||||
|
TagList nbtTagList = (TagList) nbt;
|
||||||
|
List<net.minecraft.nbt.Tag> list = new ArrayList<>();
|
||||||
|
for (Object base : nbtTagList.getList()) {
|
||||||
|
list.add(asNMS((ITag) base));
|
||||||
|
}
|
||||||
|
ListTag nbtTagList1 = new ListTag();
|
||||||
|
for (net.minecraft.nbt.Tag nbt1 : list) {
|
||||||
|
nbtTagList1.add(nbt1);
|
||||||
|
}
|
||||||
|
return nbtTagList1;
|
||||||
|
}
|
||||||
|
case 10 -> {
|
||||||
|
TagCompound tagCompound = (TagCompound) nbt;
|
||||||
|
CompoundTag nbtTagCompound = new CompoundTag();
|
||||||
|
for (String key : tagCompound.keySet()) {
|
||||||
|
ITag nbt1 = tagCompound.get(key);
|
||||||
|
nbtTagCompound.put(key, asNMS(nbt1));
|
||||||
|
}
|
||||||
|
return nbtTagCompound;
|
||||||
|
}
|
||||||
|
case 11 -> {
|
||||||
|
TagIntArray tagIntArray = (TagIntArray) nbt;
|
||||||
|
return new IntArrayTag(tagIntArray.getIntArray());
|
||||||
|
}
|
||||||
|
case 12 -> {
|
||||||
|
TagLongArray tagLongArray = (TagLongArray) nbt;
|
||||||
|
return new LongArrayTag(tagLongArray.getLongArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ITag as(net.minecraft.nbt.Tag tag) {
|
||||||
|
byte type = tag.getId();
|
||||||
|
switch (type) {
|
||||||
|
case 1:
|
||||||
|
ByteTag nbtTagByte = (ByteTag) tag;
|
||||||
|
return new TagByte(nbtTagByte.getAsByte());
|
||||||
|
case 2:
|
||||||
|
ShortTag nbtTagShort = (ShortTag) tag;
|
||||||
|
return new TagShort(nbtTagShort.getAsShort());
|
||||||
|
case 3:
|
||||||
|
IntTag nbtTagInt = (IntTag) tag;
|
||||||
|
return new TagInt(nbtTagInt.getAsInt());
|
||||||
|
case 4:
|
||||||
|
LongTag nbtTagLong = (LongTag) tag;
|
||||||
|
return new TagLong(nbtTagLong.getAsLong());
|
||||||
|
case 5:
|
||||||
|
FloatTag nbtTagFloat = (FloatTag) tag;
|
||||||
|
return new TagFloat(nbtTagFloat.getAsFloat());
|
||||||
|
case 6:
|
||||||
|
DoubleTag nbtTagDouble = (DoubleTag) tag;
|
||||||
|
return new TagDouble(nbtTagDouble.getAsDouble());
|
||||||
|
case 7:
|
||||||
|
ByteArrayTag tagByteArray = (ByteArrayTag) tag;
|
||||||
|
return new TagByteArray(tagByteArray.getAsByteArray());
|
||||||
|
case 8:
|
||||||
|
StringTag nbtTagString = (StringTag) tag;
|
||||||
|
return new TagString(nbtTagString.getAsString());
|
||||||
|
case 9:
|
||||||
|
ListTag nbtTagList = (ListTag) tag;
|
||||||
|
List<ITag> list = new ArrayList<>();
|
||||||
|
for (net.minecraft.nbt.Tag base : nbtTagList) {
|
||||||
|
list.add(as(base));
|
||||||
|
}
|
||||||
|
return new TagList(list);
|
||||||
|
case 10:
|
||||||
|
CompoundTag nbtTagCompound = (CompoundTag) tag;
|
||||||
|
Map<String, ITag> map = new HashMap<>();
|
||||||
|
for (String key : nbtTagCompound.getAllKeys()) {
|
||||||
|
map.put(key, as(nbtTagCompound.get(key)));
|
||||||
|
}
|
||||||
|
return new TagCompound(map);
|
||||||
|
case 11:
|
||||||
|
IntArrayTag nbtTagIntArray = (IntArrayTag) tag;
|
||||||
|
return new TagIntArray(nbtTagIntArray.getAsIntArray());
|
||||||
|
case 12:
|
||||||
|
LongArrayTag nbtTagLongArray = (LongArrayTag) tag;
|
||||||
|
return new TagLongArray(nbtTagLongArray.getAsLongArray());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,39 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.nbt;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
public class NBTHelper {
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static INBT convert(Object object) {
|
|
||||||
if (object instanceof Byte) {
|
|
||||||
return new NBTByte((byte) object);
|
|
||||||
} else if (object instanceof Short) {
|
|
||||||
return new NBTShort((short) object);
|
|
||||||
} else if (object instanceof Integer) {
|
|
||||||
return new NBTInt((int) object);
|
|
||||||
} else if (object instanceof Long) {
|
|
||||||
return new NBTLong((long) object);
|
|
||||||
} else if (object instanceof Float) {
|
|
||||||
return new NBTFloat((float) object);
|
|
||||||
} else if (object instanceof Double) {
|
|
||||||
return new NBTDouble((double) object);
|
|
||||||
} else if (object instanceof byte[]) {
|
|
||||||
return new NBTByteArray((byte[]) object);
|
|
||||||
} else if (object instanceof String) {
|
|
||||||
return new NBTString((String) object);
|
|
||||||
} else if (object instanceof int[]) {
|
|
||||||
return new NBTIntArray((int[]) object);
|
|
||||||
} else if (object instanceof long[]) {
|
|
||||||
return new NBTLongArray((long[]) object);
|
|
||||||
} else if (object instanceof Boolean) {
|
|
||||||
return new NBTByte((byte) ((boolean)object ? 1 : 0));
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Object convertNMSNBT(INBT nbt) {
|
|
||||||
return INBT.asNMS(nbt);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,7 +1,10 @@
|
||||||
package com.io.yutian.elementoriginlib.nbt;
|
package com.io.yutian.elementoriginlib.nbt;
|
||||||
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import com.io.yutian.elementoriginlib.serialize.serializers.ItemStackDeserializer;
|
||||||
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack;
|
import net.minecraft.core.component.DataComponents;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.world.item.component.CustomData;
|
||||||
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@ -21,38 +24,38 @@ public class NBTItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public NBTCompound getTag() {
|
public TagCompound getTag() {
|
||||||
NBTTagCompound tag = nmsItemStack.w();
|
CompoundTag tag = nmsItemStack.getComponents().get(DataComponents.CUSTOM_DATA).getUnsafe();
|
||||||
if (tag == null) {
|
if (tag == null) {
|
||||||
tag = new NBTTagCompound();
|
tag = new CompoundTag();
|
||||||
}
|
}
|
||||||
return (NBTCompound) INBT.as(tag);
|
return (TagCompound) ITag.as(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean has(String key) {
|
public boolean has(String key) {
|
||||||
NBTCompound nbtCompound = getTag();
|
TagCompound tagCompound = getTag();
|
||||||
return nbtCompound.hasKey(key);
|
return tagCompound.hasKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean has(String key, int type) {
|
public boolean has(String key, int type) {
|
||||||
NBTCompound nbtCompound = getTag();
|
TagCompound tagCompound = getTag();
|
||||||
return nbtCompound.hasKey(key, type);
|
return tagCompound.hasKey(key, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public INBT get(String key) {
|
public ITag get(String key) {
|
||||||
NBTCompound nbtCompound = getTag();
|
TagCompound tagCompound = getTag();
|
||||||
return nbtCompound.hasKey(key) ? nbtCompound.get(key) : null;
|
return tagCompound.hasKey(key) ? tagCompound.get(key) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void editTag(Consumer<NBTCompound> consumer) {
|
public void editTag(Consumer<TagCompound> consumer) {
|
||||||
NBTCompound tag = getTag();
|
TagCompound tag = getTag();
|
||||||
consumer.accept(tag);
|
consumer.accept(tag);
|
||||||
setTag(tag);
|
setTag(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTag(NBTCompound nbtCompound) {
|
public void setTag(TagCompound tagCompound) {
|
||||||
nmsItemStack.c((NBTTagCompound) INBT.asNMS(nbtCompound));
|
nmsItemStack.set(DataComponents.CUSTOM_DATA, CustomData.of((CompoundTag) ITag.asNMS(tagCompound)));
|
||||||
resultItemStack = CraftItemStack.asBukkitCopy(nmsItemStack);
|
resultItemStack = CraftItemStack.asBukkitCopy(nmsItemStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,8 +75,8 @@ public class NBTItem {
|
||||||
return new NBTItem(itemStack);
|
return new NBTItem(itemStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NBTItem build(NBTCompound nbtCompound) {
|
public static NBTItem build(TagCompound tagCompound) {
|
||||||
net.minecraft.world.item.ItemStack nmsItemStack = net.minecraft.world.item.ItemStack.a((NBTTagCompound) INBT.asNMS(nbtCompound));
|
net.minecraft.world.item.ItemStack nmsItemStack = net.minecraft.world.item.ItemStack.parse(ItemStackDeserializer.getRegistry(), ITag.asNMS(tagCompound)).get();
|
||||||
return new NBTItem(CraftItemStack.asBukkitCopy(nmsItemStack));
|
return new NBTItem(CraftItemStack.asBukkitCopy(nmsItemStack));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
package com.io.yutian.elementoriginlib.nbt;
|
package com.io.yutian.elementoriginlib.nbt;
|
||||||
|
|
||||||
public class NBTByte extends NBTNumber {
|
public class TagByte extends TagNumber {
|
||||||
|
|
||||||
public static byte TYPE_ID = 1;
|
public static byte TYPE_ID = 1;
|
||||||
|
|
||||||
private byte value;
|
private byte value;
|
||||||
|
|
||||||
public NBTByte(byte value) {
|
public TagByte(byte value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBTByte() {
|
public TagByte() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -53,8 +53,8 @@ public class NBTByte extends NBTNumber {
|
||||||
return this.value;
|
return this.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NBTByte a(boolean var0) {
|
public static TagByte a(boolean var0) {
|
||||||
return var0 ? new NBTByte((byte) 1) : new NBTByte((byte) 0);
|
return var0 ? new TagByte((byte) 1) : new TagByte((byte) 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -62,8 +62,8 @@ public class NBTByte extends NBTNumber {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
NBTByte nbtByte = (NBTByte) o;
|
TagByte tagByte = (TagByte) o;
|
||||||
return value == nbtByte.value;
|
return value == tagByte.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -2,13 +2,13 @@ package com.io.yutian.elementoriginlib.nbt;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class NBTByteArray implements INBT {
|
public class TagByteArray implements ITag {
|
||||||
|
|
||||||
public static byte TYPE_ID = 7;
|
public static byte TYPE_ID = 7;
|
||||||
|
|
||||||
private byte[] value;
|
private byte[] value;
|
||||||
|
|
||||||
public NBTByteArray(byte[] value) {
|
public TagByteArray(byte[] value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ public class NBTByteArray implements INBT {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
NBTByteArray that = (NBTByteArray) o;
|
TagByteArray that = (TagByteArray) o;
|
||||||
return Arrays.equals(value, that.value);
|
return Arrays.equals(value, that.value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,16 @@ package com.io.yutian.elementoriginlib.nbt;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class NBTCompound implements INBT {
|
public class TagCompound implements ITag {
|
||||||
|
|
||||||
public static byte TYPE_ID = 10;
|
public static byte TYPE_ID = 10;
|
||||||
|
|
||||||
private Map<String, INBT> nbtMap = new HashMap<>();
|
private Map<String, ITag> nbtMap = new HashMap<>();
|
||||||
|
|
||||||
public NBTCompound() {
|
public TagCompound() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBTCompound(Map<String, INBT> nbtMap) {
|
public TagCompound(Map<String, ITag> nbtMap) {
|
||||||
this.nbtMap = nbtMap;
|
this.nbtMap = nbtMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ public class NBTCompound implements INBT {
|
||||||
return nbtMap.keySet();
|
return nbtMap.keySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, INBT> getMap() {
|
public Map<String, ITag> getMap() {
|
||||||
return nbtMap;
|
return nbtMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,160 +39,160 @@ public class NBTCompound implements INBT {
|
||||||
return this.nbtMap.containsKey(key) && this.nbtMap.get(key).getTypeId() == id;
|
return this.nbtMap.containsKey(key) && this.nbtMap.get(key).getTypeId() == id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBTList getList(String key) {
|
public TagList getList(String key) {
|
||||||
INBT list = this.nbtMap.get(key);
|
ITag list = this.nbtMap.get(key);
|
||||||
if (list == null || list.getTypeId() != 9) {
|
if (list == null || list.getTypeId() != 9) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (NBTList) list;
|
return (TagList) list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBTCompound getCompound(String key) {
|
public TagCompound getCompound(String key) {
|
||||||
INBT comound = this.nbtMap.get(key);
|
ITag comound = this.nbtMap.get(key);
|
||||||
if (comound == null || comound.getTypeId() != 10) {
|
if (comound == null || comound.getTypeId() != 10) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (NBTCompound) comound;
|
return (TagCompound) comound;
|
||||||
}
|
}
|
||||||
|
|
||||||
public INBT get(String key) {
|
public ITag get(String key) {
|
||||||
return this.nbtMap.get(key);
|
return this.nbtMap.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInt(String key) {
|
public int getInt(String key) {
|
||||||
INBT nbt = this.nbtMap.get(key);
|
ITag nbt = this.nbtMap.get(key);
|
||||||
if (nbt == null || nbt.getTypeId() != 3) {
|
if (nbt == null || nbt.getTypeId() != 3) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ((NBTInt) nbt).getInt();
|
return ((TagInt) nbt).getInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getString(String key) {
|
public String getString(String key) {
|
||||||
INBT nbt = this.nbtMap.get(key);
|
ITag nbt = this.nbtMap.get(key);
|
||||||
if (nbt == null || nbt.getTypeId() != 8) {
|
if (nbt == null || nbt.getTypeId() != 8) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return ((NBTString) nbt).getString();
|
return ((TagString) nbt).getString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getDouble(String key) {
|
public double getDouble(String key) {
|
||||||
INBT nbt = this.nbtMap.get(key);
|
ITag nbt = this.nbtMap.get(key);
|
||||||
if (nbt == null || nbt.getTypeId() != 6) {
|
if (nbt == null || nbt.getTypeId() != 6) {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
return ((NBTDouble) nbt).getDouble();
|
return ((TagDouble) nbt).getDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getFloat(String key) {
|
public float getFloat(String key) {
|
||||||
INBT nbt = this.nbtMap.get(key);
|
ITag nbt = this.nbtMap.get(key);
|
||||||
if (nbt == null || nbt.getTypeId() != 5) {
|
if (nbt == null || nbt.getTypeId() != 5) {
|
||||||
return 0.0F;
|
return 0.0F;
|
||||||
}
|
}
|
||||||
return ((NBTFloat) nbt).getFloat();
|
return ((TagFloat) nbt).getFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getShort(String key) {
|
public short getShort(String key) {
|
||||||
INBT nbt = this.nbtMap.get(key);
|
ITag nbt = this.nbtMap.get(key);
|
||||||
if (nbt == null || nbt.getTypeId() != 2) {
|
if (nbt == null || nbt.getTypeId() != 2) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ((NBTShort) nbt).getShort();
|
return ((TagShort) nbt).getShort();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getLong(String key) {
|
public long getLong(String key) {
|
||||||
INBT nbt = this.nbtMap.get(key);
|
ITag nbt = this.nbtMap.get(key);
|
||||||
if (nbt == null || nbt.getTypeId() != 4) {
|
if (nbt == null || nbt.getTypeId() != 4) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ((NBTLong) nbt).getLong();
|
return ((TagLong) nbt).getLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte getByte(String key) {
|
public byte getByte(String key) {
|
||||||
INBT nbt = this.nbtMap.get(key);
|
ITag nbt = this.nbtMap.get(key);
|
||||||
if (nbt == null || nbt.getTypeId() != 1) {
|
if (nbt == null || nbt.getTypeId() != 1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ((NBTByte) nbt).getByte();
|
return ((TagByte) nbt).getByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBTByteArray getByteArray(String key) {
|
public TagByteArray getByteArray(String key) {
|
||||||
INBT nbt = this.nbtMap.get(key);
|
ITag nbt = this.nbtMap.get(key);
|
||||||
if (nbt == null || nbt.getTypeId() != 7) {
|
if (nbt == null || nbt.getTypeId() != 7) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (NBTByteArray) nbt;
|
return (TagByteArray) nbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBTIntArray getIntArray(String key) {
|
public TagIntArray getIntArray(String key) {
|
||||||
INBT nbt = this.nbtMap.get(key);
|
ITag nbt = this.nbtMap.get(key);
|
||||||
if (nbt == null || nbt.getTypeId() != 11) {
|
if (nbt == null || nbt.getTypeId() != 11) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (NBTIntArray) nbt;
|
return (TagIntArray) nbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBTLongArray getLongArray(String key) {
|
public TagLongArray getLongArray(String key) {
|
||||||
INBT nbt = this.nbtMap.get(key);
|
ITag nbt = this.nbtMap.get(key);
|
||||||
if (nbt == null || nbt.getTypeId() != 12) {
|
if (nbt == null || nbt.getTypeId() != 12) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (NBTLongArray) nbt;
|
return (TagLongArray) nbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getBoolean(String key) {
|
public boolean getBoolean(String key) {
|
||||||
INBT nbt = this.nbtMap.get(key);
|
ITag nbt = this.nbtMap.get(key);
|
||||||
if (nbt == null || nbt.getTypeId() != 1) {
|
if (nbt == null || nbt.getTypeId() != 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return ((NBTByte) nbt).getByte() != 0;
|
return ((TagByte) nbt).getByte() != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UUID getUUID(String key) {
|
public UUID getUUID(String key) {
|
||||||
INBT nbt = this.nbtMap.get(key);
|
ITag nbt = this.nbtMap.get(key);
|
||||||
if (nbt == null || nbt.getTypeId() != 11) {
|
if (nbt == null || nbt.getTypeId() != 11) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return a(((NBTIntArray) nbt).getIntArray());
|
return a(((TagIntArray) nbt).getIntArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void put(String key, INBT nbt) {
|
public void put(String key, ITag nbt) {
|
||||||
this.nbtMap.put(key, nbt);
|
this.nbtMap.put(key, nbt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putString(String key, String value) {
|
public void putString(String key, String value) {
|
||||||
put(key, new NBTString(value));
|
put(key, new TagString(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putInt(String key, int value) {
|
public void putInt(String key, int value) {
|
||||||
put(key, new NBTInt(value));
|
put(key, new TagInt(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putShort(String key, short value) {
|
public void putShort(String key, short value) {
|
||||||
put(key, new NBTShort(value));
|
put(key, new TagShort(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putDouble(String key, double value) {
|
public void putDouble(String key, double value) {
|
||||||
put(key, new NBTDouble(value));
|
put(key, new TagDouble(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putLong(String key, long value) {
|
public void putLong(String key, long value) {
|
||||||
put(key, new NBTLong(value));
|
put(key, new TagLong(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putFloat(String key, float value) {
|
public void putFloat(String key, float value) {
|
||||||
put(key, new NBTFloat(value));
|
put(key, new TagFloat(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putByte(String key, byte value) {
|
public void putByte(String key, byte value) {
|
||||||
put(key, new NBTByte(value));
|
put(key, new TagByte(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putBoolean(String key, boolean value) {
|
public void putBoolean(String key, boolean value) {
|
||||||
put(key, NBTByte.a(value));
|
put(key, TagByte.a(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putUUID(String key, UUID uuid) {
|
public void putUUID(String key, UUID uuid) {
|
||||||
put(key, new NBTIntArray(a(uuid)));
|
put(key, new TagIntArray(a(uuid)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static UUID a(int[] var0) {
|
private static UUID a(int[] var0) {
|
||||||
|
@ -224,19 +224,19 @@ public class NBTCompound implements INBT {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
NBTCompound that = (NBTCompound) o;
|
TagCompound that = (TagCompound) o;
|
||||||
Map<String, INBT> nbtMap1 = this.nbtMap;
|
Map<String, ITag> nbtMap1 = this.nbtMap;
|
||||||
Map<String, INBT> nbtMap2 = that.nbtMap;
|
Map<String, ITag> nbtMap2 = that.nbtMap;
|
||||||
if (nbtMap1.size() != nbtMap2.size()) {
|
if (nbtMap1.size() != nbtMap2.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (Map.Entry<String, INBT> entry : nbtMap1.entrySet()) {
|
for (Map.Entry<String, ITag> entry : nbtMap1.entrySet()) {
|
||||||
String key = entry.getKey();
|
String key = entry.getKey();
|
||||||
INBT value = entry.getValue();
|
ITag value = entry.getValue();
|
||||||
if (!nbtMap2.containsKey(key)) {
|
if (!nbtMap2.containsKey(key)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
INBT nbt2 = nbtMap2.get(key);
|
ITag nbt2 = nbtMap2.get(key);
|
||||||
Object object1 = value.getValue();
|
Object object1 = value.getValue();
|
||||||
Object object2 = nbt2.getValue();
|
Object object2 = nbt2.getValue();
|
||||||
if (value == null && nbt2 != null) {
|
if (value == null && nbt2 != null) {
|
|
@ -1,16 +1,16 @@
|
||||||
package com.io.yutian.elementoriginlib.nbt;
|
package com.io.yutian.elementoriginlib.nbt;
|
||||||
|
|
||||||
public class NBTDouble extends NBTNumber {
|
public class TagDouble extends TagNumber {
|
||||||
|
|
||||||
public static byte TYPE_ID = 6;
|
public static byte TYPE_ID = 6;
|
||||||
|
|
||||||
private double value;
|
private double value;
|
||||||
|
|
||||||
public NBTDouble(double value) {
|
public TagDouble(double value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBTDouble() {
|
public TagDouble() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -58,8 +58,8 @@ public class NBTDouble extends NBTNumber {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
NBTDouble nbtDouble = (NBTDouble) o;
|
TagDouble tagDouble = (TagDouble) o;
|
||||||
return Double.compare(value, nbtDouble.value) == 0;
|
return Double.compare(value, tagDouble.value) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -1,12 +1,12 @@
|
||||||
package com.io.yutian.elementoriginlib.nbt;
|
package com.io.yutian.elementoriginlib.nbt;
|
||||||
|
|
||||||
public class NBTFloat extends NBTNumber {
|
public class TagFloat extends TagNumber {
|
||||||
|
|
||||||
public static byte TYPE_ID = 5;
|
public static byte TYPE_ID = 5;
|
||||||
|
|
||||||
private float value;
|
private float value;
|
||||||
|
|
||||||
public NBTFloat(float value) {
|
public TagFloat(float value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,8 +55,8 @@ public class NBTFloat extends NBTNumber {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
NBTFloat nbtFloat = (NBTFloat) o;
|
TagFloat tagFloat = (TagFloat) o;
|
||||||
return Float.compare(value, nbtFloat.value) == 0;
|
return Float.compare(value, tagFloat.value) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
116
src/main/java/com/io/yutian/elementoriginlib/nbt/TagHelper.java
Normal file
116
src/main/java/com/io/yutian/elementoriginlib/nbt/TagHelper.java
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
package com.io.yutian.elementoriginlib.nbt;
|
||||||
|
|
||||||
|
import net.minecraft.nbt.*;
|
||||||
|
import net.minecraft.nbt.Tag;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
public class TagHelper {
|
||||||
|
|
||||||
|
public static Object tagToJson(Tag tag) {
|
||||||
|
switch (tag.getId()) {
|
||||||
|
case 1: // ByteTag
|
||||||
|
return ((ByteTag) tag).getAsByte();
|
||||||
|
case 2: // ShortTag
|
||||||
|
return ((ShortTag) tag).getAsShort();
|
||||||
|
case 3: // IntTag
|
||||||
|
return ((IntTag) tag).getAsInt();
|
||||||
|
case 4: // LongTag
|
||||||
|
return ((LongTag) tag).getAsLong();
|
||||||
|
case 5: // FloatTag
|
||||||
|
return ((FloatTag) tag).getAsFloat();
|
||||||
|
case 6: // DoubleTag
|
||||||
|
return ((DoubleTag) tag).getAsDouble();
|
||||||
|
case 7: // ByteArrayTag
|
||||||
|
return ((ByteArrayTag) tag).getAsByteArray();
|
||||||
|
case 8: // StringTag
|
||||||
|
return ((StringTag) tag).getAsString();
|
||||||
|
case 9: // ListTag
|
||||||
|
ListTag listTag = (ListTag) tag;
|
||||||
|
JSONArray jsonArray = new JSONArray();
|
||||||
|
for (Tag element : listTag) {
|
||||||
|
jsonArray.put(tagToJson(element));
|
||||||
|
}
|
||||||
|
return jsonArray;
|
||||||
|
case 10: // CompoundTag
|
||||||
|
CompoundTag compoundTag = (CompoundTag) tag;
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
for (String key : compoundTag.getAllKeys()) {
|
||||||
|
jsonObject.put(key, tagToJson(compoundTag.get(key)));
|
||||||
|
}
|
||||||
|
return jsonObject;
|
||||||
|
case 11:
|
||||||
|
return ((IntArrayTag) tag).getAsIntArray();
|
||||||
|
case 12:
|
||||||
|
return ((LongArrayTag) tag).getAsLongArray();
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unsupported Tag type: " + tag.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Tag jsonToTag(Object json) {
|
||||||
|
if (json instanceof JSONObject) {
|
||||||
|
JSONObject jsonObject = (JSONObject) json;
|
||||||
|
CompoundTag compoundTag = new CompoundTag();
|
||||||
|
for (String key : jsonObject.keySet()) {
|
||||||
|
compoundTag.put(key, jsonToTag(jsonObject.get(key)));
|
||||||
|
}
|
||||||
|
return compoundTag;
|
||||||
|
} else if (json instanceof JSONArray) {
|
||||||
|
JSONArray jsonArray = (JSONArray) json;
|
||||||
|
ListTag listTag = new ListTag();
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
listTag.add(jsonToTag(jsonArray.get(i)));
|
||||||
|
}
|
||||||
|
return listTag;
|
||||||
|
} else if (json instanceof String) {
|
||||||
|
return StringTag.valueOf((String) json);
|
||||||
|
} else if (json instanceof Integer) {
|
||||||
|
return IntTag.valueOf((Integer) json);
|
||||||
|
} else if (json instanceof Long) {
|
||||||
|
return LongTag.valueOf((Long) json);
|
||||||
|
} else if (json instanceof Double) {
|
||||||
|
return DoubleTag.valueOf((Double) json);
|
||||||
|
} else if (json instanceof Float) {
|
||||||
|
return FloatTag.valueOf((Float) json);
|
||||||
|
} else if (json instanceof Byte) {
|
||||||
|
return ByteTag.valueOf((Byte) json);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unsupported JSON type: " + json.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static ITag convert(Object object) {
|
||||||
|
if (object instanceof Byte) {
|
||||||
|
return new TagByte((byte) object);
|
||||||
|
} else if (object instanceof Short) {
|
||||||
|
return new TagShort((short) object);
|
||||||
|
} else if (object instanceof Integer) {
|
||||||
|
return new TagInt((int) object);
|
||||||
|
} else if (object instanceof Long) {
|
||||||
|
return new TagLong((long) object);
|
||||||
|
} else if (object instanceof Float) {
|
||||||
|
return new TagFloat((float) object);
|
||||||
|
} else if (object instanceof Double) {
|
||||||
|
return new TagDouble((double) object);
|
||||||
|
} else if (object instanceof byte[]) {
|
||||||
|
return new TagByteArray((byte[]) object);
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
return new TagString((String) object);
|
||||||
|
} else if (object instanceof int[]) {
|
||||||
|
return new TagIntArray((int[]) object);
|
||||||
|
} else if (object instanceof long[]) {
|
||||||
|
return new TagLongArray((long[]) object);
|
||||||
|
} else if (object instanceof Boolean) {
|
||||||
|
return new TagByte((byte) ((boolean)object ? 1 : 0));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object convertNMSNBT(ITag nbt) {
|
||||||
|
return ITag.asNMS(nbt);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
package com.io.yutian.elementoriginlib.nbt;
|
package com.io.yutian.elementoriginlib.nbt;
|
||||||
|
|
||||||
public class NBTInt extends NBTNumber {
|
public class TagInt extends TagNumber {
|
||||||
|
|
||||||
public static byte TYPE_ID = 3;
|
public static byte TYPE_ID = 3;
|
||||||
|
|
||||||
private int value;
|
private int value;
|
||||||
|
|
||||||
public NBTInt(int value) {
|
public TagInt(int value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,8 +55,8 @@ public class NBTInt extends NBTNumber {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
NBTInt nbtInt = (NBTInt) o;
|
TagInt tagInt = (TagInt) o;
|
||||||
return value == nbtInt.value;
|
return value == tagInt.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -2,13 +2,13 @@ package com.io.yutian.elementoriginlib.nbt;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class NBTIntArray implements INBT {
|
public class TagIntArray implements ITag {
|
||||||
|
|
||||||
public static byte TYPE_ID = 11;
|
public static byte TYPE_ID = 11;
|
||||||
|
|
||||||
private int[] value;
|
private int[] value;
|
||||||
|
|
||||||
public NBTIntArray(int[] value) {
|
public TagIntArray(int[] value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ public class NBTIntArray implements INBT {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
NBTIntArray that = (NBTIntArray) o;
|
TagIntArray that = (TagIntArray) o;
|
||||||
return Arrays.equals(value, that.value);
|
return Arrays.equals(value, that.value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,18 +4,18 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class NBTList<T extends INBT> implements INBT {
|
public class TagList<T extends ITag> implements ITag {
|
||||||
|
|
||||||
public static byte TYPE_ID = 9;
|
public static byte TYPE_ID = 9;
|
||||||
|
|
||||||
private List<T> value = new ArrayList<>();
|
private List<T> value = new ArrayList<>();
|
||||||
private byte type = 0;
|
private byte type = 0;
|
||||||
|
|
||||||
public NBTList(List<T> value) {
|
public TagList(List<T> value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBTList() {
|
public TagList() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<T> getList() {
|
public List<T> getList() {
|
||||||
|
@ -72,8 +72,8 @@ public class NBTList<T extends INBT> implements INBT {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
NBTList<?> nbtList = (NBTList<?>) o;
|
TagList<?> tagList = (TagList<?>) o;
|
||||||
return type == nbtList.type && Objects.equals(value, nbtList.value);
|
return type == tagList.type && Objects.equals(value, tagList.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -1,16 +1,16 @@
|
||||||
package com.io.yutian.elementoriginlib.nbt;
|
package com.io.yutian.elementoriginlib.nbt;
|
||||||
|
|
||||||
public class NBTLong extends NBTNumber {
|
public class TagLong extends TagNumber {
|
||||||
|
|
||||||
public static byte TYPE_ID = 4;
|
public static byte TYPE_ID = 4;
|
||||||
|
|
||||||
private long value;
|
private long value;
|
||||||
|
|
||||||
public NBTLong(long value) {
|
public TagLong(long value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBTLong() {
|
public TagLong() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -65,8 +65,8 @@ public class NBTLong extends NBTNumber {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
NBTLong nbtLong = (NBTLong) o;
|
TagLong tagLong = (TagLong) o;
|
||||||
return value == nbtLong.value;
|
return value == tagLong.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -2,13 +2,13 @@ package com.io.yutian.elementoriginlib.nbt;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class NBTLongArray implements INBT {
|
public class TagLongArray implements ITag {
|
||||||
|
|
||||||
public static byte TYPE_ID = 12;
|
public static byte TYPE_ID = 12;
|
||||||
|
|
||||||
private long[] value;
|
private long[] value;
|
||||||
|
|
||||||
public NBTLongArray(long[] value) {
|
public TagLongArray(long[] value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ public class NBTLongArray implements INBT {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
NBTLongArray that = (NBTLongArray) o;
|
TagLongArray that = (TagLongArray) o;
|
||||||
return Arrays.equals(value, that.value);
|
return Arrays.equals(value, that.value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.io.yutian.elementoriginlib.nbt;
|
package com.io.yutian.elementoriginlib.nbt;
|
||||||
|
|
||||||
public abstract class NBTNumber implements INBT {
|
public abstract class TagNumber implements ITag {
|
||||||
|
|
||||||
public abstract long getLong();
|
public abstract long getLong();
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
package com.io.yutian.elementoriginlib.nbt;
|
package com.io.yutian.elementoriginlib.nbt;
|
||||||
|
|
||||||
public class NBTShort extends NBTNumber {
|
public class TagShort extends TagNumber {
|
||||||
|
|
||||||
public static byte TYPE_ID = 2;
|
public static byte TYPE_ID = 2;
|
||||||
|
|
||||||
private short value;
|
private short value;
|
||||||
|
|
||||||
public NBTShort(short value) {
|
public TagShort(short value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBTShort() {
|
public TagShort() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -58,7 +58,7 @@ public class NBTShort extends NBTNumber {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
NBTShort nbtShort = (NBTShort) o;
|
TagShort nbtShort = (TagShort) o;
|
||||||
return value == nbtShort.value;
|
return value == nbtShort.value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,17 +2,17 @@ package com.io.yutian.elementoriginlib.nbt;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class NBTString implements INBT {
|
public class TagString implements ITag {
|
||||||
|
|
||||||
public static byte TYPE_ID = 8;
|
public static byte TYPE_ID = 8;
|
||||||
|
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
public NBTString(String value) {
|
public TagString(String value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NBTString() {
|
public TagString() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getString() {
|
public String getString() {
|
||||||
|
@ -34,8 +34,8 @@ public class NBTString implements INBT {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
NBTString nbtString = (NBTString) o;
|
TagString tagString = (TagString) o;
|
||||||
return Objects.equals(value, nbtString.value);
|
return Objects.equals(value, tagString.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -1,5 +1,7 @@
|
||||||
package com.io.yutian.elementoriginlib.point;
|
package com.io.yutian.elementoriginlib.point;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
@ -11,7 +13,8 @@ public class DirectionPoint extends Point {
|
||||||
private float yaw;
|
private float yaw;
|
||||||
private float pitch;
|
private float pitch;
|
||||||
|
|
||||||
public DirectionPoint(int x, int y, int z, float yaw, float pitch) {
|
@JsonCreator
|
||||||
|
public DirectionPoint(@JsonProperty("x") int x, @JsonProperty("y") int y, @JsonProperty("z") int z, @JsonProperty("yaw") float yaw, @JsonProperty("pitch") float pitch) {
|
||||||
super(x, y, z);
|
super(x, y, z);
|
||||||
this.yaw = yaw;
|
this.yaw = yaw;
|
||||||
this.pitch = pitch;
|
this.pitch = pitch;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.io.yutian.elementoriginlib.point;
|
package com.io.yutian.elementoriginlib.point;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
@ -12,7 +13,7 @@ public class Point {
|
||||||
private double y;
|
private double y;
|
||||||
private double z;
|
private double z;
|
||||||
|
|
||||||
public Point(int x, int y, int z) {
|
public Point(@JsonProperty("x") int x, @JsonProperty("y") int y, @JsonProperty("z") int z) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.io.yutian.elementoriginlib.point;
|
package com.io.yutian.elementoriginlib.point;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.redis;
|
|
||||||
|
|
||||||
import redis.clients.jedis.Jedis;
|
|
||||||
|
|
||||||
public interface IJedisGetter {
|
|
||||||
|
|
||||||
Jedis getRedis();
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,108 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.redis;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.ElementOriginLib;
|
|
||||||
import com.io.yutian.elementoriginlib.util.Pair;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
import redis.clients.jedis.Jedis;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class RedisCacheSyncTimer {
|
|
||||||
|
|
||||||
private static final String LOCK_KEY = "sync_lock";
|
|
||||||
private static final int LOCK_EXPIRE_SECONDS = 290;
|
|
||||||
private final Map<Plugin, PluginInfo> pluginInfos = new HashMap<>();
|
|
||||||
|
|
||||||
private BukkitTask task;
|
|
||||||
|
|
||||||
public RedisCacheSyncTimer() {
|
|
||||||
task = new BukkitRunnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (pluginInfos.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (Map.Entry<Plugin, PluginInfo> entry : pluginInfos.entrySet()) {
|
|
||||||
Plugin plugin = entry.getKey();
|
|
||||||
if (!plugin.isEnabled()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
PluginInfo pluginInfo = entry.getValue();
|
|
||||||
String lockKey = LOCK_KEY + "_" + plugin.getName();
|
|
||||||
IJedisGetter jedisGetter = pluginInfo.getJedisGetter();
|
|
||||||
try (Jedis jedis = jedisGetter.getRedis()) {
|
|
||||||
long lockResult = jedis.setnx(lockKey, "locked");
|
|
||||||
if (lockResult != 1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
jedis.expire(lockKey, LOCK_EXPIRE_SECONDS);
|
|
||||||
for (Map.Entry<Pair<String, String>, RedisCacheSynchronizer> entry1 : entry.getValue().getSynchronizers().entrySet()) {
|
|
||||||
Pair<String, String> key = entry1.getKey();
|
|
||||||
RedisCacheSynchronizer synchronizer = entry1.getValue();
|
|
||||||
String k1 = key.first();
|
|
||||||
String k2 = key.second();
|
|
||||||
for (String k : jedis.keys(k1+":*")) {
|
|
||||||
String data = null;
|
|
||||||
if (k2 == null) {
|
|
||||||
data = jedis.get(k);
|
|
||||||
} else {
|
|
||||||
data = jedis.hget(k, k2);
|
|
||||||
}
|
|
||||||
if (data != null) {
|
|
||||||
String finalData = data;
|
|
||||||
synchronizer.sync(k, finalData);
|
|
||||||
if (k2 == null) {
|
|
||||||
jedis.del(k);
|
|
||||||
} else {
|
|
||||||
jedis.hdel(k, k2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.runTaskTimerAsynchronously(ElementOriginLib.inst(), 1200L, 5 * 60 * 20L);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerSynchronizer(Plugin plugin, IJedisGetter jedisGetter, Pair<String, String> key, RedisCacheSynchronizer synchronizer) {
|
|
||||||
PluginInfo pluginInfo = pluginInfos.computeIfAbsent(plugin, k -> new PluginInfo(jedisGetter));
|
|
||||||
pluginInfo.addSynchronizer(key, synchronizer);
|
|
||||||
pluginInfos.put(plugin, pluginInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
class PluginInfo {
|
|
||||||
|
|
||||||
private IJedisGetter jedisGetter;
|
|
||||||
private Map<Pair<String, String>, RedisCacheSynchronizer> synchronizers;
|
|
||||||
|
|
||||||
public PluginInfo(IJedisGetter jedisGetter) {
|
|
||||||
this.jedisGetter = jedisGetter;
|
|
||||||
this.synchronizers = new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addSynchronizer(Pair<String, String> key, RedisCacheSynchronizer synchronizer) {
|
|
||||||
if (key == null || synchronizer == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (synchronizers.containsKey(key)) {
|
|
||||||
throw new IllegalArgumentException("Key already registered: " + key);
|
|
||||||
}
|
|
||||||
synchronizers.put(key, synchronizer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IJedisGetter getJedisGetter() {
|
|
||||||
return jedisGetter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Pair<String, String>, RedisCacheSynchronizer> getSynchronizers() {
|
|
||||||
return synchronizers;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.redis;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface RedisCacheSynchronizer {
|
|
||||||
|
|
||||||
void sync(String key, String data);
|
|
||||||
|
|
||||||
}
|
|
|
@ -12,7 +12,7 @@ import java.io.File;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class RedisIO implements IJedisGetter {
|
public class RedisIO {
|
||||||
|
|
||||||
private JedisPool jedisPool;
|
private JedisPool jedisPool;
|
||||||
|
|
||||||
|
@ -80,8 +80,4 @@ public class RedisIO implements IJedisGetter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Jedis getRedis() {
|
|
||||||
return jedisPool.getResource();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.serialize;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
public interface ISerializable<T> {
|
|
||||||
|
|
||||||
JSONObject serialize();
|
|
||||||
|
|
||||||
T deserialize(JSONObject jsonObject);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,189 +1,59 @@
|
||||||
package com.io.yutian.elementoriginlib.serialize;
|
package com.io.yutian.elementoriginlib.serialize;
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.exception.SerializeException;
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
|
||||||
|
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||||
|
import com.io.yutian.elementoriginlib.serialize.serializers.ItemStackDeserializer;
|
||||||
import com.io.yutian.elementoriginlib.serialize.serializers.ItemStackSerializer;
|
import com.io.yutian.elementoriginlib.serialize.serializers.ItemStackSerializer;
|
||||||
|
import com.io.yutian.elementoriginlib.serialize.serializers.UUIDDeserializer;
|
||||||
import com.io.yutian.elementoriginlib.serialize.serializers.UUIDSerializer;
|
import com.io.yutian.elementoriginlib.serialize.serializers.UUIDSerializer;
|
||||||
import com.io.yutian.elementoriginlib.util.ReflectionUtil;
|
|
||||||
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import sun.misc.Unsafe;
|
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
import java.util.UUID;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class SerializeHelper {
|
public class SerializeHelper {
|
||||||
|
|
||||||
private static Map<Class<?>, Serializer> serializers = new HashMap<>();
|
private static final ObjectMapper objectMapper;
|
||||||
|
|
||||||
public static <T, V> void registerSerializer(Class<T> clazz, Serializer<T> serializer) {
|
|
||||||
serializers.put(clazz, serializer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> JSONObject serialize(T obj) throws SerializeException {
|
|
||||||
try {
|
|
||||||
JSONObject jsonObject = new JSONObject();
|
|
||||||
Class clazz = obj.getClass();
|
|
||||||
for (Field field : clazz.getDeclaredFields()) {
|
|
||||||
field.setAccessible(true);
|
|
||||||
if (field.isAnnotationPresent(SerializeIgnore.class)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Object value = field.get(obj);
|
|
||||||
if (value == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Object serializeValue = serializeValue(value);
|
|
||||||
jsonObject.put(field.getName(), serializeValue);
|
|
||||||
}
|
|
||||||
return jsonObject;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw new SerializeException(obj.getClass(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T deserialize(Class<T> clazz, JSONObject jsonObject) throws SerializeException {
|
|
||||||
try {
|
|
||||||
Unsafe unsafe = ReflectionUtil.getUnsafe();
|
|
||||||
T instance = (T) unsafe.allocateInstance(clazz);
|
|
||||||
for (Field field : clazz.getDeclaredFields()) {
|
|
||||||
field.setAccessible(true);
|
|
||||||
if (field.isAnnotationPresent(SerializeIgnore.class)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String name = field.getName();
|
|
||||||
if (name.equalsIgnoreCase("this$0")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!jsonObject.has(name)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Object value = jsonObject.get(name);
|
|
||||||
if (value == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Object deserializeValue = deserializeValue(field, field.getType(), value);
|
|
||||||
ReflectionUtil.setFieldUsingUnsafe(field, instance, deserializeValue);
|
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw new SerializeException(clazz, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object deserializeValue(Field field, Class clazz0, Object value) throws SerializeException {
|
|
||||||
Class clazz = clazz0;
|
|
||||||
if (WRAPPER_TO_PRIMITIVE.containsKey(clazz)) {
|
|
||||||
clazz = WRAPPER_TO_PRIMITIVE.get(clazz);
|
|
||||||
}
|
|
||||||
if (serializers.containsKey(clazz)) {
|
|
||||||
Serializer serializer = serializers.get(clazz);
|
|
||||||
return serializer.deserialize(value);
|
|
||||||
}
|
|
||||||
if (ISerializable.class.isAssignableFrom(clazz)) {
|
|
||||||
ISerializable iSerializable = (ISerializable) value;
|
|
||||||
JSONObject jsonObject = (JSONObject) value;
|
|
||||||
return iSerializable.deserialize(jsonObject);
|
|
||||||
} else if (clazz.isPrimitive() || clazz.equals(String.class)) {
|
|
||||||
return value;
|
|
||||||
} else if (clazz.isEnum()) {
|
|
||||||
return Enum.valueOf((Class<Enum>) clazz, (String) value);
|
|
||||||
} else if (clazz.isArray()) {
|
|
||||||
JSONArray jsonArray = (JSONArray) value;
|
|
||||||
int length = jsonArray.length();
|
|
||||||
Object object = Array.newInstance(clazz.getComponentType(), length);
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
Array.set(object, i, deserializeValue(field, clazz.getComponentType(), jsonArray.get(i)));
|
|
||||||
}
|
|
||||||
return object;
|
|
||||||
} else if (List.class.isAssignableFrom(clazz)) {
|
|
||||||
List list = new ArrayList();
|
|
||||||
JSONArray jsonArray = (JSONArray) value;
|
|
||||||
Type genericType = field.getGenericType();
|
|
||||||
Class<?> elementType = (Class<?>) ((ParameterizedType) genericType).getActualTypeArguments()[0];
|
|
||||||
for (int i = 0; i < jsonArray.length(); i++) {
|
|
||||||
list.add(deserializeValue(field, elementType, jsonArray.get(i)));
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
} else if (Map.class.isAssignableFrom(clazz)) {
|
|
||||||
Map map = new HashMap();
|
|
||||||
Type genericType = field.getGenericType();
|
|
||||||
Class<?> valueType = (Class<?>) ((ParameterizedType) genericType).getActualTypeArguments()[1];
|
|
||||||
JSONObject jsonObject = (JSONObject) value;
|
|
||||||
for (String key : jsonObject.keySet()) {
|
|
||||||
map.put(key, deserializeValue(field, valueType, jsonObject.get(key)));
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
} else {
|
|
||||||
return deserialize(clazz, (JSONObject) value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object serializeValue(Object value) throws SerializeException {
|
|
||||||
Class clazz = value.getClass();
|
|
||||||
if (WRAPPER_TO_PRIMITIVE.containsKey(clazz)) {
|
|
||||||
clazz = WRAPPER_TO_PRIMITIVE.get(clazz);
|
|
||||||
}
|
|
||||||
if (serializers.containsKey(clazz)) {
|
|
||||||
Serializer serializer = serializers.get(clazz);
|
|
||||||
return serializer.serialize(value);
|
|
||||||
}
|
|
||||||
if (ISerializable.class.isAssignableFrom(clazz)) {
|
|
||||||
ISerializable iSerializable = (ISerializable) value;
|
|
||||||
return iSerializable.serialize();
|
|
||||||
} else if (clazz.isPrimitive() || clazz.equals(String.class)) {
|
|
||||||
return value;
|
|
||||||
} else if (clazz.isEnum()) {
|
|
||||||
return ((Enum) value).name();
|
|
||||||
} else if (clazz.isArray()) {
|
|
||||||
Class elementType = clazz.getComponentType();
|
|
||||||
JSONArray jsonArray = new JSONArray();
|
|
||||||
int length = Array.getLength(value);
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
Object element = Array.get(value, i);
|
|
||||||
jsonArray.put(serializeValue(element));
|
|
||||||
}
|
|
||||||
return jsonArray;
|
|
||||||
} else if (List.class.isAssignableFrom(clazz)) {
|
|
||||||
List list = (List) value;
|
|
||||||
JSONArray jsonArray = new JSONArray();
|
|
||||||
for (Object element : list) {
|
|
||||||
jsonArray.put(serializeValue(element));
|
|
||||||
}
|
|
||||||
return jsonArray;
|
|
||||||
} else if (Map.class.isAssignableFrom(clazz)) {
|
|
||||||
Map map = (Map) value;
|
|
||||||
JSONObject jsonObject = new JSONObject();
|
|
||||||
for (Object key : map.keySet()) {
|
|
||||||
jsonObject.put(key.toString(), serializeValue(map.get(key)));
|
|
||||||
}
|
|
||||||
return jsonObject;
|
|
||||||
} else {
|
|
||||||
return serialize(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Map<Class<?>, Class<?>> WRAPPER_TO_PRIMITIVE = new HashMap<>();
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
WRAPPER_TO_PRIMITIVE.put(Boolean.class, boolean.class);
|
objectMapper = new ObjectMapper();
|
||||||
WRAPPER_TO_PRIMITIVE.put(Byte.class, byte.class);
|
|
||||||
WRAPPER_TO_PRIMITIVE.put(Short.class, short.class);
|
|
||||||
WRAPPER_TO_PRIMITIVE.put(Character.class, char.class);
|
|
||||||
WRAPPER_TO_PRIMITIVE.put(Integer.class, int.class);
|
|
||||||
WRAPPER_TO_PRIMITIVE.put(Long.class, long.class);
|
|
||||||
WRAPPER_TO_PRIMITIVE.put(Float.class, float.class);
|
|
||||||
WRAPPER_TO_PRIMITIVE.put(Double.class, double.class);
|
|
||||||
WRAPPER_TO_PRIMITIVE.put(CraftItemStack.class, ItemStack.class);
|
|
||||||
|
|
||||||
registerSerializer(UUID.class, new UUIDSerializer());
|
objectMapper.setVisibility(
|
||||||
registerSerializer(ItemStack.class, new ItemStackSerializer());
|
VisibilityChecker.Std.defaultInstance()
|
||||||
|
.withFieldVisibility(JsonAutoDetect.Visibility.ANY)
|
||||||
|
.withGetterVisibility(JsonAutoDetect.Visibility.NONE)
|
||||||
|
.withSetterVisibility(JsonAutoDetect.Visibility.NONE)
|
||||||
|
.withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)
|
||||||
|
.withCreatorVisibility(JsonAutoDetect.Visibility.NONE)
|
||||||
|
);
|
||||||
|
|
||||||
|
SimpleModule module = new SimpleModule();
|
||||||
|
module.addSerializer(UUID.class, new UUIDSerializer());
|
||||||
|
module.addDeserializer(UUID.class, new UUIDDeserializer());
|
||||||
|
|
||||||
|
module.addSerializer(ItemStack.class, new ItemStackSerializer());
|
||||||
|
module.addDeserializer(ItemStack.class, new ItemStackDeserializer());
|
||||||
|
objectMapper.registerModule(module);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String serialize(Object obj) {
|
||||||
|
try {
|
||||||
|
return objectMapper.writeValueAsString(obj);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException("Failed to serialize object: " + obj, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T deserialize(String json, Class<T> clazz) {
|
||||||
|
try {
|
||||||
|
return objectMapper.readValue(json, clazz);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException("Failed to deserialize JSON: " + json, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.serialize;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
@Target(ElementType.FIELD)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface SerializeIgnore {
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.serialize;
|
|
||||||
|
|
||||||
public interface Serializer<T> {
|
|
||||||
|
|
||||||
Object serialize(T value);
|
|
||||||
|
|
||||||
T deserialize(Object value);
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.io.yutian.elementoriginlib.serialize.serializers;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JacksonException;
|
||||||
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
|
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||||
|
import com.io.yutian.elementoriginlib.nbt.TagHelper;
|
||||||
|
import net.minecraft.core.HolderLookup;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class ItemStackDeserializer extends JsonDeserializer<ItemStack> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
|
||||||
|
CompoundTag compoundTag = (CompoundTag) TagHelper.jsonToTag(new JSONObject(jsonParser.readValueAsTree().toString()));
|
||||||
|
net.minecraft.world.item.ItemStack nmsItemStack = net.minecraft.world.item.ItemStack.parse(getRegistry(), compoundTag).get();
|
||||||
|
return CraftItemStack.asCraftMirror(nmsItemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HolderLookup.Provider getRegistry() {
|
||||||
|
MinecraftServer minecraftServer = MinecraftServer.getServer();
|
||||||
|
return minecraftServer.registryAccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,95 +1,20 @@
|
||||||
package com.io.yutian.elementoriginlib.serialize.serializers;
|
package com.io.yutian.elementoriginlib.serialize.serializers;
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.serialize.Serializer;
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||||
import net.minecraft.nbt.*;
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack;
|
import com.io.yutian.elementoriginlib.nbt.TagHelper;
|
||||||
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
public class ItemStackSerializer implements Serializer<ItemStack> {
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class ItemStackSerializer extends JsonSerializer<ItemStack> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object serialize(ItemStack value) {
|
public void serialize(ItemStack value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||||
JSONObject jsonObject = new JSONObject();
|
|
||||||
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(value);
|
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(value);
|
||||||
jsonObject.put("id", nmsItemStack.c().d().j().g());
|
gen.writeRawValue(TagHelper.tagToJson(nmsItemStack.save(ItemStackDeserializer.getRegistry())).toString());
|
||||||
jsonObject.put("Count", nmsItemStack.J());
|
|
||||||
NBTTagCompound nbtTagCompound = nmsItemStack.w();
|
|
||||||
JSONObject tagJsonObject = new JSONObject();
|
|
||||||
for (String key : nbtTagCompound.e()) {
|
|
||||||
NBTBase nbtBase = nbtTagCompound.c(key);
|
|
||||||
tagJsonObject.put(key, serializeNBT(nbtBase));
|
|
||||||
}
|
|
||||||
jsonObject.put("tag", tagJsonObject);
|
|
||||||
return jsonObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object serializeNBT(NBTBase nbtBase) {
|
|
||||||
byte type = nbtBase.b();
|
|
||||||
switch (type) {
|
|
||||||
case 1:
|
|
||||||
NBTTagByte nbtTagByte = (NBTTagByte) nbtBase;
|
|
||||||
return nbtTagByte.i();
|
|
||||||
case 2:
|
|
||||||
NBTTagShort nbtTagShort = (NBTTagShort) nbtBase;
|
|
||||||
return nbtTagShort.h();
|
|
||||||
case 3:
|
|
||||||
NBTTagInt nbtTagInt = (NBTTagInt) nbtBase;
|
|
||||||
return nbtTagInt.g();
|
|
||||||
case 4:
|
|
||||||
NBTTagLong nbtTagLong = (NBTTagLong) nbtBase;
|
|
||||||
return nbtTagLong.f();
|
|
||||||
case 5:
|
|
||||||
NBTTagFloat nbtTagFloat = (NBTTagFloat) nbtBase;
|
|
||||||
return nbtTagFloat.k();
|
|
||||||
case 6:
|
|
||||||
NBTTagDouble nbtTagDouble = (NBTTagDouble) nbtBase;
|
|
||||||
return nbtTagDouble.j();
|
|
||||||
case 7:
|
|
||||||
NBTTagByteArray tagByteArray = (NBTTagByteArray) nbtBase;
|
|
||||||
return tagByteArray.e();
|
|
||||||
case 8:
|
|
||||||
NBTTagString nbtTagString = (NBTTagString) nbtBase;
|
|
||||||
return nbtTagString.t_();
|
|
||||||
case 9:
|
|
||||||
NBTTagList nbtTagList = (NBTTagList) nbtBase;
|
|
||||||
JSONArray jsonArray = new JSONArray();
|
|
||||||
for (net.minecraft.nbt.NBTBase base : nbtTagList) {
|
|
||||||
jsonArray.put(serializeNBT(base));
|
|
||||||
}
|
|
||||||
return jsonArray;
|
|
||||||
case 10:
|
|
||||||
NBTTagCompound nbtTagCompound = (NBTTagCompound) nbtBase;
|
|
||||||
JSONObject jsonObject = new JSONObject();
|
|
||||||
for (String key : nbtTagCompound.e()) {
|
|
||||||
jsonObject.put(key, serializeNBT(nbtTagCompound.c(key)));
|
|
||||||
}
|
|
||||||
return jsonObject;
|
|
||||||
case 11:
|
|
||||||
NBTTagIntArray nbtTagIntArray = (NBTTagIntArray) nbtBase;
|
|
||||||
return nbtTagIntArray.g();
|
|
||||||
case 12:
|
|
||||||
NBTTagLongArray nbtTagLongArray = (NBTTagLongArray) nbtBase;
|
|
||||||
return nbtTagLongArray.g();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemStack deserialize(Object value) {
|
|
||||||
JSONObject jsonObject = (JSONObject) value;
|
|
||||||
String arg = jsonObject.toString();
|
|
||||||
NBTTagCompound nbtTagCompound;
|
|
||||||
try {
|
|
||||||
nbtTagCompound = net.minecraft.nbt.MojangsonParser.a(arg);
|
|
||||||
} catch (CommandSyntaxException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
net.minecraft.world.item.ItemStack nmsItemStack = net.minecraft.world.item.ItemStack.a(nbtTagCompound);
|
|
||||||
return CraftItemStack.asCraftMirror(nmsItemStack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.io.yutian.elementoriginlib.serialize.serializers;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JacksonException;
|
||||||
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
|
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class UUIDDeserializer extends JsonDeserializer<UUID> {
|
||||||
|
@Override
|
||||||
|
public UUID deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
|
||||||
|
return UUID.fromString(jsonParser.getText());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,17 +1,15 @@
|
||||||
package com.io.yutian.elementoriginlib.serialize.serializers;
|
package com.io.yutian.elementoriginlib.serialize.serializers;
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.serialize.Serializer;
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class UUIDSerializer implements Serializer<UUID> {
|
public class UUIDSerializer extends JsonSerializer<UUID> {
|
||||||
@Override
|
@Override
|
||||||
public Object serialize(UUID value) {
|
public void serialize(UUID uuid, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
|
||||||
return value.toString();
|
jsonGenerator.writeString(uuid.toString());
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UUID deserialize(Object value) {
|
|
||||||
return UUID.fromString((String) value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLManager;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLQuery;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.util.TimeDateUtils;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import com.zaxxer.hikari.HikariConfig;
|
|
||||||
import com.zaxxer.hikari.HikariDataSource;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
public class SQLHelper {
|
|
||||||
|
|
||||||
public static SQLManagerImpl createManager(
|
|
||||||
@NotNull String driver, @NotNull String url,
|
|
||||||
@NotNull String username, @Nullable String password) {
|
|
||||||
HikariConfig config = new HikariConfig();
|
|
||||||
config.setDriverClassName(driver);
|
|
||||||
config.setJdbcUrl(url);
|
|
||||||
config.setUsername(username);
|
|
||||||
config.setPassword(password);
|
|
||||||
return createManager(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SQLManagerImpl createManager(@NotNull Properties properties) {
|
|
||||||
return createManager(new HikariConfig(properties));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SQLManagerImpl createManager(@NotNull HikariConfig config) {
|
|
||||||
return new SQLManagerImpl(new HikariDataSource(config));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void shutdownManager(SQLManager manager, boolean forceClose, boolean outputActiveQuery) {
|
|
||||||
if (!manager.getActiveQuery().isEmpty()) {
|
|
||||||
manager.getLogger().warn("There are " + manager.getActiveQuery().size() + " connections still running");
|
|
||||||
for (SQLQuery value : manager.getActiveQuery().values()) {
|
|
||||||
if (outputActiveQuery) {
|
|
||||||
manager.getLogger().warn(String.format("#%s -> %s", value.getAction().getShortID(), value.getSQLContent()));
|
|
||||||
manager.getLogger().warn(String.format("- execute at %s", TimeDateUtils.getTimeString(value.getExecuteTime())));
|
|
||||||
}
|
|
||||||
if (forceClose) value.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (manager.getDataSource() instanceof HikariDataSource) {
|
|
||||||
//Close hikari pool
|
|
||||||
((HikariDataSource) manager.getDataSource()).close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void shutdownManager(SQLManager manager) {
|
|
||||||
shutdownManager(manager, true, manager.isDebugMode());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,102 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.action;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLExceptionHandler;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLFunction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLHandler;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public abstract class AbstractSQLAction<T> implements SQLAction<T> {
|
|
||||||
|
|
||||||
protected final @NotNull String sqlContent;
|
|
||||||
private final @NotNull SQLManagerImpl sqlManager;
|
|
||||||
private final @NotNull UUID uuid;
|
|
||||||
private final long createNanoTime;
|
|
||||||
|
|
||||||
public AbstractSQLAction(@NotNull SQLManagerImpl manager, @NotNull String sql) {
|
|
||||||
this(manager, sql, System.nanoTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
public AbstractSQLAction(@NotNull SQLManagerImpl manager, @NotNull String sql, @NotNull UUID uuid) {
|
|
||||||
this(manager, sql, uuid, System.nanoTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
public AbstractSQLAction(@NotNull SQLManagerImpl manager, @NotNull String sql, long createNanoTime) {
|
|
||||||
this(manager, sql, UUID.randomUUID(), createNanoTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AbstractSQLAction(@NotNull SQLManagerImpl manager, @NotNull String sql,
|
|
||||||
@NotNull UUID uuid, long createNanoTime) {
|
|
||||||
Objects.requireNonNull(manager);
|
|
||||||
Objects.requireNonNull(sql);
|
|
||||||
Objects.requireNonNull(uuid);
|
|
||||||
this.sqlManager = manager;
|
|
||||||
this.sqlContent = sql;
|
|
||||||
this.uuid = uuid;
|
|
||||||
this.createNanoTime = createNanoTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull UUID getActionUUID() {
|
|
||||||
return this.uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getShortID() {
|
|
||||||
return getActionUUID().toString().substring(0, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getCreateTime(TimeUnit unit) {
|
|
||||||
return unit.convert(createNanoTime, TimeUnit.NANOSECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getSQLContent() {
|
|
||||||
return this.sqlContent.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull SQLManagerImpl getManager() {
|
|
||||||
return this.sqlManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void debugMessage(List<Object[]> params) {
|
|
||||||
if (getManager().isDebugMode()) {
|
|
||||||
try {
|
|
||||||
getManager().getDebugHandler().beforeExecute(this, params);
|
|
||||||
} catch (Exception exception) {
|
|
||||||
exception.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("FutureReturnValueIgnored")
|
|
||||||
public void executeAsync(SQLHandler<T> success, SQLExceptionHandler failure) {
|
|
||||||
getManager().getExecutorPool().submit(() -> {
|
|
||||||
try {
|
|
||||||
T returnedValue = execute();
|
|
||||||
if (success != null) success.accept(returnedValue);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
handleException(failure, e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull <R> CompletableFuture<R> executeFuture(@NotNull SQLFunction<T, R> handler) {
|
|
||||||
CompletableFuture<R> future = new CompletableFuture<>();
|
|
||||||
executeAsync((t -> future.complete(handler.apply(t))), (e, q) -> future.completeExceptionally(e));
|
|
||||||
return future;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.action;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.PreparedSQLUpdateBatchAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.util.StatementUtil;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class PreparedSQLBatchUpdateActionImpl<T extends Number>
|
|
||||||
extends AbstractSQLAction<List<T>>
|
|
||||||
implements PreparedSQLUpdateBatchAction<T> {
|
|
||||||
|
|
||||||
boolean returnKeys = false;
|
|
||||||
@NotNull List<Object[]> allParams = new ArrayList<>();
|
|
||||||
|
|
||||||
protected final @NotNull Class<T> numberClass;
|
|
||||||
|
|
||||||
public PreparedSQLBatchUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull Class<T> numberClass,
|
|
||||||
@NotNull String sql) {
|
|
||||||
super(manager, sql);
|
|
||||||
this.numberClass = numberClass;
|
|
||||||
this.allParams = new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedSQLBatchUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull Class<T> numberClass,
|
|
||||||
@NotNull UUID uuid, @NotNull String sql) {
|
|
||||||
super(manager, sql, uuid);
|
|
||||||
this.numberClass = numberClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PreparedSQLBatchUpdateActionImpl<T> setAllParams(Iterable<Object[]> allParams) {
|
|
||||||
List<Object[]> paramsList = new ArrayList<>();
|
|
||||||
allParams.forEach(paramsList::add);
|
|
||||||
this.allParams = paramsList;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PreparedSQLBatchUpdateActionImpl<T> addParamsBatch(Object... params) {
|
|
||||||
this.allParams.add(params);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PreparedSQLBatchUpdateActionImpl<T> returnGeneratedKeys() {
|
|
||||||
this.returnKeys = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <N extends Number> PreparedSQLBatchUpdateActionImpl<N> returnGeneratedKeys(Class<N> keyTypeClass) {
|
|
||||||
return new PreparedSQLBatchUpdateActionImpl<>(getManager(), keyTypeClass, getActionUUID(), getSQLContent())
|
|
||||||
.setAllParams(allParams).returnGeneratedKeys();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull List<T> execute() throws SQLException {
|
|
||||||
debugMessage(allParams);
|
|
||||||
|
|
||||||
try (Connection connection = getManager().getConnection()) {
|
|
||||||
try (PreparedStatement statement = StatementUtil.createPrepareStatementBatch(
|
|
||||||
connection, getSQLContent(), allParams, returnKeys
|
|
||||||
)) {
|
|
||||||
int[] executed = statement.executeBatch();
|
|
||||||
|
|
||||||
if (!returnKeys) {
|
|
||||||
return Arrays.stream(executed).mapToObj(numberClass::cast).collect(Collectors.toList());
|
|
||||||
} else {
|
|
||||||
try (ResultSet resultSet = statement.getGeneratedKeys()) {
|
|
||||||
List<T> generatedKeys = new ArrayList<>();
|
|
||||||
while (resultSet.next()) {
|
|
||||||
generatedKeys.add(resultSet.getObject(1, numberClass));
|
|
||||||
}
|
|
||||||
return generatedKeys;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,94 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.action;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.PreparedSQLUpdateAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.SQLUpdateAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.util.StatementUtil;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class PreparedSQLUpdateActionImpl<T extends Number>
|
|
||||||
extends SQLUpdateActionImpl<T>
|
|
||||||
implements PreparedSQLUpdateAction<T> {
|
|
||||||
|
|
||||||
Object[] params;
|
|
||||||
|
|
||||||
public PreparedSQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull Class<T> numberClass,
|
|
||||||
@NotNull String sql) {
|
|
||||||
this(manager, numberClass, sql, (Object[]) null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedSQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull Class<T> numberClass,
|
|
||||||
@NotNull String sql, @Nullable List<Object> params) {
|
|
||||||
this(manager, numberClass, sql, params == null ? null : params.toArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedSQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull Class<T> numberClass,
|
|
||||||
@NotNull String sql, @Nullable Object[] params) {
|
|
||||||
super(manager, numberClass, sql);
|
|
||||||
this.params = params;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreparedSQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull Class<T> numberClass,
|
|
||||||
@NotNull UUID uuid, @NotNull String sql,
|
|
||||||
Object[] params) {
|
|
||||||
super(manager, numberClass, uuid, sql);
|
|
||||||
this.params = params;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PreparedSQLUpdateActionImpl<T> setParams(Object... params) {
|
|
||||||
this.params = params;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PreparedSQLUpdateActionImpl<T> setParams(@Nullable Iterable<Object> params) {
|
|
||||||
if (params == null) {
|
|
||||||
return setParams((Object[]) null);
|
|
||||||
} else {
|
|
||||||
List<Object> paramsList = new ArrayList<>();
|
|
||||||
params.forEach(paramsList::add);
|
|
||||||
return setParams(paramsList.toArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull T execute() throws SQLException {
|
|
||||||
debugMessage(Collections.singletonList(params));
|
|
||||||
|
|
||||||
try (Connection connection = getManager().getConnection()) {
|
|
||||||
|
|
||||||
try (PreparedStatement statement = StatementUtil.createPrepareStatement(
|
|
||||||
connection, getSQLContent(), params, returnGeneratedKeys
|
|
||||||
)) {
|
|
||||||
|
|
||||||
int changes = statement.executeUpdate();
|
|
||||||
if (!returnGeneratedKeys) return numberClass.cast(changes);
|
|
||||||
else {
|
|
||||||
try (ResultSet resultSet = statement.getGeneratedKeys()) {
|
|
||||||
return resultSet.next() ? resultSet.getObject(1, numberClass) : numberClass.cast(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <N extends Number> SQLUpdateAction<N> returnGeneratedKey(Class<N> keyTypeClass) {
|
|
||||||
PreparedSQLUpdateActionImpl<N> newAction = new PreparedSQLUpdateActionImpl<>(getManager(), keyTypeClass, getActionUUID(), getSQLContent(), params);
|
|
||||||
newAction.returnGeneratedKey();
|
|
||||||
return newAction;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.action;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.SQLUpdateAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class SQLUpdateActionImpl<T extends Number>
|
|
||||||
extends AbstractSQLAction<T>
|
|
||||||
implements SQLUpdateAction<T> {
|
|
||||||
|
|
||||||
protected final @NotNull Class<T> numberClass;
|
|
||||||
|
|
||||||
protected boolean returnGeneratedKeys = false;
|
|
||||||
|
|
||||||
public SQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull Class<T> numberClass,
|
|
||||||
@NotNull String sql) {
|
|
||||||
super(manager, sql);
|
|
||||||
this.numberClass = numberClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SQLUpdateActionImpl(@NotNull SQLManagerImpl manager, @NotNull Class<T> numberClass,
|
|
||||||
@NotNull UUID uuid, @NotNull String sql) {
|
|
||||||
super(manager, sql, uuid);
|
|
||||||
this.numberClass = numberClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull T execute() throws SQLException {
|
|
||||||
debugMessage(new ArrayList<>());
|
|
||||||
|
|
||||||
try (Connection connection = getManager().getConnection()) {
|
|
||||||
try (Statement statement = connection.createStatement()) {
|
|
||||||
|
|
||||||
if (!returnGeneratedKeys) {
|
|
||||||
return numberClass.cast(statement.executeUpdate(getSQLContent()));
|
|
||||||
} else {
|
|
||||||
statement.executeUpdate(getSQLContent(), Statement.RETURN_GENERATED_KEYS);
|
|
||||||
|
|
||||||
try (ResultSet resultSet = statement.getGeneratedKeys()) {
|
|
||||||
return resultSet.next() ? resultSet.getObject(1, numberClass) : numberClass.cast(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLUpdateAction<T> returnGeneratedKey() {
|
|
||||||
this.returnGeneratedKeys = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <N extends Number> SQLUpdateAction<N> returnGeneratedKey(Class<N> keyTypeClass) {
|
|
||||||
return new SQLUpdateActionImpl<>(getManager(), keyTypeClass, getActionUUID(), getSQLContent()).returnGeneratedKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.action;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.SQLUpdateBatchAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class SQLUpdateBatchActionImpl
|
|
||||||
extends AbstractSQLAction<List<Integer>>
|
|
||||||
implements SQLUpdateBatchAction {
|
|
||||||
|
|
||||||
protected final List<String> sqlContents = new ArrayList<>();
|
|
||||||
|
|
||||||
public SQLUpdateBatchActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) {
|
|
||||||
super(manager, sql);
|
|
||||||
this.sqlContents.add(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull List<String> getSQLContents() {
|
|
||||||
return this.sqlContents;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLUpdateBatchAction addBatch(@NotNull String sql) {
|
|
||||||
Objects.requireNonNull(sql, "sql could not be null");
|
|
||||||
this.sqlContents.add(sql);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull List<Integer> execute() throws SQLException {
|
|
||||||
debugMessage(new ArrayList<>());
|
|
||||||
|
|
||||||
try (Connection connection = getManager().getConnection()) {
|
|
||||||
|
|
||||||
try (Statement statement = connection.createStatement()) {
|
|
||||||
|
|
||||||
for (String content : this.sqlContents) {
|
|
||||||
statement.addBatch(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
int[] executed = statement.executeBatch();
|
|
||||||
|
|
||||||
return Arrays.stream(executed).boxed().collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,83 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.action.query;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.query.PreparedQueryAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.util.StatementUtil;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class PreparedQueryActionImpl extends QueryActionImpl implements PreparedQueryAction {
|
|
||||||
|
|
||||||
Consumer<PreparedStatement> handler;
|
|
||||||
Object[] params;
|
|
||||||
|
|
||||||
public PreparedQueryActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) {
|
|
||||||
super(manager, sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PreparedQueryActionImpl setParams(@Nullable Object... params) {
|
|
||||||
this.params = params;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PreparedQueryActionImpl setParams(@Nullable Iterable<Object> params) {
|
|
||||||
if (params == null) {
|
|
||||||
return setParams((Object[]) null);
|
|
||||||
} else {
|
|
||||||
List<Object> paramsList = new ArrayList<>();
|
|
||||||
params.forEach(paramsList::add);
|
|
||||||
return setParams(paramsList.toArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PreparedQueryActionImpl handleStatement(@Nullable Consumer<PreparedStatement> statement) {
|
|
||||||
this.handler = statement;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull SQLQueryImpl execute() throws SQLException {
|
|
||||||
debugMessage(Collections.singletonList(params));
|
|
||||||
|
|
||||||
Connection connection = getManager().getConnection();
|
|
||||||
PreparedStatement preparedStatement;
|
|
||||||
try {
|
|
||||||
if (handler == null) {
|
|
||||||
preparedStatement = StatementUtil.createPrepareStatement(connection, getSQLContent(), this.params);
|
|
||||||
} else {
|
|
||||||
preparedStatement = connection.prepareStatement(getSQLContent());
|
|
||||||
handler.accept(preparedStatement);
|
|
||||||
}
|
|
||||||
} catch (SQLException exception) {
|
|
||||||
connection.close();
|
|
||||||
throw exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
SQLQueryImpl query = new SQLQueryImpl(
|
|
||||||
getManager(), this,
|
|
||||||
connection, preparedStatement,
|
|
||||||
preparedStatement.executeQuery()
|
|
||||||
);
|
|
||||||
getManager().getActiveQuery().put(getActionUUID(), query);
|
|
||||||
return query;
|
|
||||||
} catch (SQLException exception) {
|
|
||||||
preparedStatement.close();
|
|
||||||
connection.close();
|
|
||||||
throw exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.action.query;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.action.AbstractSQLAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLQuery;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.query.QueryAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLExceptionHandler;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLHandler;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class QueryActionImpl extends AbstractSQLAction<SQLQuery> implements QueryAction {
|
|
||||||
|
|
||||||
public QueryActionImpl(@NotNull SQLManagerImpl manager, @NotNull String sql) {
|
|
||||||
super(manager, sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull SQLQueryImpl execute() throws SQLException {
|
|
||||||
debugMessage(new ArrayList<>());
|
|
||||||
|
|
||||||
Connection connection = getManager().getConnection();
|
|
||||||
Statement statement;
|
|
||||||
|
|
||||||
try {
|
|
||||||
statement = connection.createStatement();
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
connection.close();
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
SQLQueryImpl query = new SQLQueryImpl(
|
|
||||||
getManager(), this,
|
|
||||||
connection, statement,
|
|
||||||
statement.executeQuery(getSQLContent())
|
|
||||||
);
|
|
||||||
getManager().getActiveQuery().put(getActionUUID(), query);
|
|
||||||
|
|
||||||
return query;
|
|
||||||
} catch (SQLException exception) {
|
|
||||||
statement.close();
|
|
||||||
connection.close();
|
|
||||||
throw exception;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void executeAsync(SQLHandler<SQLQuery> success, SQLExceptionHandler failure) {
|
|
||||||
getManager().getExecutorPool().submit(() -> {
|
|
||||||
try (SQLQueryImpl query = execute()) {
|
|
||||||
if (success != null) success.accept(query);
|
|
||||||
} catch (SQLException exception) {
|
|
||||||
handleException(failure, exception);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,97 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.action.query;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLQuery;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class SQLQueryImpl implements SQLQuery {
|
|
||||||
|
|
||||||
protected final long executeTime;
|
|
||||||
|
|
||||||
protected final SQLManagerImpl sqlManager;
|
|
||||||
protected final Connection connection;
|
|
||||||
protected final Statement statement;
|
|
||||||
protected final ResultSet resultSet;
|
|
||||||
protected QueryActionImpl queryAction;
|
|
||||||
|
|
||||||
public SQLQueryImpl(
|
|
||||||
SQLManagerImpl sqlManager, QueryActionImpl queryAction,
|
|
||||||
Connection connection, Statement statement, ResultSet resultSet
|
|
||||||
) {
|
|
||||||
this(sqlManager, queryAction, connection, statement, resultSet, System.nanoTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
public SQLQueryImpl(
|
|
||||||
SQLManagerImpl sqlManager, QueryActionImpl queryAction,
|
|
||||||
Connection connection, Statement statement, ResultSet resultSet,
|
|
||||||
long executeTime
|
|
||||||
) {
|
|
||||||
this.executeTime = executeTime;
|
|
||||||
this.sqlManager = sqlManager;
|
|
||||||
this.queryAction = queryAction;
|
|
||||||
this.connection = connection;
|
|
||||||
this.statement = statement;
|
|
||||||
this.resultSet = resultSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getExecuteTime(TimeUnit timeUnit) {
|
|
||||||
return timeUnit.convert(this.executeTime, TimeUnit.NANOSECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLManagerImpl getManager() {
|
|
||||||
return this.sqlManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public QueryActionImpl getAction() {
|
|
||||||
return this.queryAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResultSet getResultSet() {
|
|
||||||
return this.resultSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getSQLContent() {
|
|
||||||
return getAction().getSQLContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
try {
|
|
||||||
if (getResultSet() != null && !getResultSet().isClosed()) getResultSet().close();
|
|
||||||
if (getStatement() != null && !getStatement().isClosed()) getStatement().close();
|
|
||||||
if (getConnection() != null && !getConnection().isClosed()) getConnection().close();
|
|
||||||
|
|
||||||
if (getManager().isDebugMode()) {
|
|
||||||
try {
|
|
||||||
getManager().getDebugHandler().afterQuery(this, getExecuteTime(TimeUnit.NANOSECONDS), System.nanoTime());
|
|
||||||
} catch (Exception ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
getManager().getActiveQuery().remove(getAction().getActionUUID());
|
|
||||||
} catch (SQLException e) {
|
|
||||||
getAction().handleException(getAction().defaultExceptionHandler(), e);
|
|
||||||
}
|
|
||||||
this.queryAction = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Statement getStatement() {
|
|
||||||
return this.statement;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Connection getConnection() {
|
|
||||||
return this.connection;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,254 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLExceptionHandler;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLFunction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLHandler;
|
|
||||||
import org.jetbrains.annotations.Contract;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SQLAction 是用于承载SQL语句并进行处理、返回的基本类。
|
|
||||||
*
|
|
||||||
* <ul>
|
|
||||||
* <li>同步执行 {@link #execute()}, {@link #execute(SQLFunction, SQLExceptionHandler)}
|
|
||||||
* <br>同步执行方法中有会抛出异常的方法与不抛出异常的方法,
|
|
||||||
* <br>若选择不抛出异常,则返回值可能为空,需要特殊处理。</li>
|
|
||||||
*
|
|
||||||
* <li>异步执行 {@link #executeAsync(SQLHandler, SQLExceptionHandler)}
|
|
||||||
* <br>异步执行时将提供成功与异常两种处理方式
|
|
||||||
* <br>可自行选择是否对数据或异常进行处理
|
|
||||||
* <br>默认的异常处理器为 {@link #defaultExceptionHandler()}
|
|
||||||
* <br>若有特殊需要,可通过{@link #setExceptionHandler(SQLExceptionHandler)} 方法修改默认的处理器</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @param <T> 需要返回的类型
|
|
||||||
* @author CarmJos
|
|
||||||
* @since 0.0.1
|
|
||||||
*/
|
|
||||||
public interface SQLAction<T> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到该Action的UUID
|
|
||||||
*
|
|
||||||
* @return UUID
|
|
||||||
*/
|
|
||||||
@NotNull UUID getActionUUID();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到短八位格式的UUID
|
|
||||||
*
|
|
||||||
* @return UUID(8)
|
|
||||||
*/
|
|
||||||
@NotNull String getShortID();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到该Action的创建时间。
|
|
||||||
* <br>注意,此处获得的时间非时间戳毫秒数,仅用于计算耗时。
|
|
||||||
*
|
|
||||||
* @return 创建时间 (毫秒)
|
|
||||||
*/
|
|
||||||
default long getCreateTime() {
|
|
||||||
return getCreateTime(TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到该Action的创建时间
|
|
||||||
* <br>注意,此处获得的时间非时间戳毫秒数,仅用于计算耗时。
|
|
||||||
*
|
|
||||||
* @param unit 时间单位
|
|
||||||
* @return 创建时间
|
|
||||||
*/
|
|
||||||
long getCreateTime(TimeUnit unit);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到该Action所要执行的源SQL语句
|
|
||||||
*
|
|
||||||
* @return 源SQL语句
|
|
||||||
*/
|
|
||||||
@NotNull String getSQLContent();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到该Action所要执行的源SQL语句列表。
|
|
||||||
*
|
|
||||||
* @return 源SQL语句列表
|
|
||||||
*/
|
|
||||||
default @NotNull List<String> getSQLContents() {
|
|
||||||
return Collections.singletonList(getSQLContent());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到承载该Action的对应{@link SQLManager}
|
|
||||||
*
|
|
||||||
* @return {@link SQLManager}
|
|
||||||
*/
|
|
||||||
@NotNull SQLManager getManager();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行该Action对应的SQL语句
|
|
||||||
*
|
|
||||||
* @return 指定数据类型
|
|
||||||
* @throws SQLException 当SQL操作出现问题时抛出
|
|
||||||
*/
|
|
||||||
@NotNull T execute() throws SQLException;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行语句并返回值
|
|
||||||
*
|
|
||||||
* @param exceptionHandler 异常处理器 默认为 {@link #defaultExceptionHandler()}
|
|
||||||
* @return 指定类型数据
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
default T execute(@Nullable SQLExceptionHandler exceptionHandler) {
|
|
||||||
return execute(t -> t, exceptionHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行语句并处理返回值
|
|
||||||
*
|
|
||||||
* @param function 处理方法
|
|
||||||
* @param exceptionHandler 异常处理器 默认为 {@link #defaultExceptionHandler()}
|
|
||||||
* @param <R> 需要返回的内容
|
|
||||||
* @return 指定类型数据
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
default <R> R execute(@NotNull SQLFunction<T, R> function,
|
|
||||||
@Nullable SQLExceptionHandler exceptionHandler) {
|
|
||||||
return execute(function, null, exceptionHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行语句并处理返回值
|
|
||||||
*
|
|
||||||
* @param function 处理方法
|
|
||||||
* @param defaultResult 默认结果,若处理后的结果为null,则返回该值
|
|
||||||
* @param exceptionHandler 异常处理器 默认为 {@link #defaultExceptionHandler()}
|
|
||||||
* @param <R> 需要返回的内容
|
|
||||||
* @return 指定类型数据
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
@Contract("_,!null,_ -> !null")
|
|
||||||
default <R> R execute(@NotNull SQLFunction<T, R> function,
|
|
||||||
@Nullable R defaultResult,
|
|
||||||
@Nullable SQLExceptionHandler exceptionHandler) {
|
|
||||||
try {
|
|
||||||
return executeFunction(function, defaultResult);
|
|
||||||
} catch (SQLException exception) {
|
|
||||||
handleException(exceptionHandler, exception);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行语句并处理返回值
|
|
||||||
*
|
|
||||||
* @param function 处理方法
|
|
||||||
* @param <R> 需要返回的内容
|
|
||||||
* @return 指定类型数据
|
|
||||||
* @throws SQLException 当SQL操作出现问题时抛出
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
default <R> R executeFunction(@NotNull SQLFunction<@NotNull T, R> function) throws SQLException {
|
|
||||||
return executeFunction(function, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行语句并处理返回值
|
|
||||||
*
|
|
||||||
* @param function 处理方法
|
|
||||||
* @param defaultResult 默认结果,若处理后的结果为null,则返回该值
|
|
||||||
* @param <R> 需要返回的内容
|
|
||||||
* @return 指定类型数据
|
|
||||||
* @throws SQLException 当SQL操作出现问题时抛出
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
@Contract("_,!null -> !null")
|
|
||||||
default <R> R executeFunction(@NotNull SQLFunction<@NotNull T, R> function,
|
|
||||||
@Nullable R defaultResult) throws SQLException {
|
|
||||||
try {
|
|
||||||
R result = function.apply(execute());
|
|
||||||
return result == null ? defaultResult : result;
|
|
||||||
} catch (SQLException exception) {
|
|
||||||
throw new SQLException(exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 异步执行SQL语句,采用默认异常处理,无需返回值。
|
|
||||||
*/
|
|
||||||
default void executeAsync() {
|
|
||||||
executeAsync(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 异步执行SQL语句
|
|
||||||
*
|
|
||||||
* @param success 成功时的操作
|
|
||||||
*/
|
|
||||||
default void executeAsync(@Nullable SQLHandler<T> success) {
|
|
||||||
executeAsync(success, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 异步执行SQL语句
|
|
||||||
*
|
|
||||||
* @param success 成功时的操作
|
|
||||||
* @param failure 异常处理器 默认为 {@link SQLAction#defaultExceptionHandler()}
|
|
||||||
*/
|
|
||||||
void executeAsync(@Nullable SQLHandler<T> success,
|
|
||||||
@Nullable SQLExceptionHandler failure);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 以异步Future方式执行SQL语句。
|
|
||||||
*
|
|
||||||
* @return 异步执行的Future实例,可通过 {@link Future#get()} 阻塞并等待结果。
|
|
||||||
*/
|
|
||||||
default @NotNull CompletableFuture<Void> executeFuture() {
|
|
||||||
return executeFuture((t -> null));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 以异步Future方式执行SQL语句。
|
|
||||||
*
|
|
||||||
* @return 异步执行的Future实例,可通过 {@link Future#get()} 阻塞并等待结果。
|
|
||||||
*/
|
|
||||||
<R> @NotNull CompletableFuture<R> executeFuture(@NotNull SQLFunction<T, R> handler);
|
|
||||||
|
|
||||||
default void handleException(@Nullable SQLExceptionHandler handler, SQLException exception) {
|
|
||||||
if (handler == null) handler = defaultExceptionHandler();
|
|
||||||
handler.accept(exception, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取管理器提供的默认异常处理器。
|
|
||||||
* 若未使用过 {@link #setExceptionHandler(SQLExceptionHandler)} 方法,
|
|
||||||
* 则默认返回 {@link SQLExceptionHandler#detailed(Logger)} 。
|
|
||||||
*
|
|
||||||
* @return {@link SQLExceptionHandler}
|
|
||||||
*/
|
|
||||||
default SQLExceptionHandler defaultExceptionHandler() {
|
|
||||||
return getManager().getExceptionHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定通用的异常处理器。
|
|
||||||
* <br> 在使用 {@link #execute(SQLExceptionHandler)} 等相关方法时,若传入的处理器为null,则会采用此处理器。
|
|
||||||
* <br> 若该方法传入参数为 null,则会使用 {@link #defaultExceptionHandler()} 。
|
|
||||||
*
|
|
||||||
* @param handler 异常处理器
|
|
||||||
*/
|
|
||||||
default void setExceptionHandler(@Nullable SQLExceptionHandler handler) {
|
|
||||||
getManager().setExceptionHandler(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SQLBuilder 是用于构建SQL语句以生成SQLAction执行操作的中间类。
|
|
||||||
* <br>其连接了{@link SQLManager} 与 {@link SQLAction} ,避免大量的代码堆积
|
|
||||||
* <br>也是本接口的核心功能所在
|
|
||||||
*
|
|
||||||
* @author CarmJos
|
|
||||||
*/
|
|
||||||
public interface SQLBuilder {
|
|
||||||
|
|
||||||
static @NotNull String withBackQuote(@NotNull String str) {
|
|
||||||
str = str.trim();
|
|
||||||
return !str.isEmpty() && str.charAt(0) == '`' && str.charAt(str.length() - 1) == '`' ? str : "`" + str + "`";
|
|
||||||
}
|
|
||||||
|
|
||||||
static @NotNull String withQuote(@NotNull String str) {
|
|
||||||
str = str.trim();
|
|
||||||
return !str.isEmpty() && str.charAt(0) == '\'' && str.charAt(str.length() - 1) == '\'' ? str : "'" + str + "'";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到承载该Builder的对应{@link SQLManager}
|
|
||||||
*
|
|
||||||
* @return {@link SQLManager}
|
|
||||||
*/
|
|
||||||
@NotNull SQLManager getManager();
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,316 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.PreparedSQLUpdateAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.PreparedSQLUpdateBatchAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.SQLUpdateAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.SQLUpdateBatchAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.builder.*;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLBiFunction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLDebugHandler;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLExceptionHandler;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLFunction;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DatabaseMetaData;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SQLManager 是EasySQL的核心类,用于管理数据库连接,提供数据库操作的方法。
|
|
||||||
*
|
|
||||||
* @author CarmJos
|
|
||||||
*/
|
|
||||||
public interface SQLManager {
|
|
||||||
|
|
||||||
Logger getLogger();
|
|
||||||
|
|
||||||
boolean isDebugMode();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取用于执行 {@link SQLAction#executeAsync()} 的线程池。
|
|
||||||
* <br> 默认线程池为 {@link #defaultExecutorPool(String)} 。
|
|
||||||
*
|
|
||||||
* @return {@link ExecutorService}
|
|
||||||
*/
|
|
||||||
@NotNull ExecutorService getExecutorPool();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定用于执行 {@link SQLAction#executeAsync()} 的线程池.
|
|
||||||
* <br> 默认线程池为 {@link #defaultExecutorPool(String)} 。
|
|
||||||
*
|
|
||||||
* @param executorPool {@link ExecutorService}
|
|
||||||
*/
|
|
||||||
void setExecutorPool(@NotNull ExecutorService executorPool);
|
|
||||||
|
|
||||||
static ExecutorService defaultExecutorPool(String threadName) {
|
|
||||||
return Executors.newFixedThreadPool(4, r -> {
|
|
||||||
Thread thread = new Thread(r, threadName);
|
|
||||||
thread.setDaemon(true);
|
|
||||||
return thread;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定是否启用调试模式。
|
|
||||||
* 启用调试模式后,会在每次执行SQL语句时,调用 {@link #getDebugHandler()} 来输出调试信息。
|
|
||||||
*
|
|
||||||
* @param debugMode 是否启用调试模式
|
|
||||||
*/
|
|
||||||
void setDebugMode(@NotNull Supplier<@NotNull Boolean> debugMode);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定是否启用调试模式。
|
|
||||||
* 启用调试模式后,会在每次执行SQL语句时,调用 {@link #getDebugHandler()} 来输出调试信息。
|
|
||||||
*
|
|
||||||
* @param enable 是否启用调试模式
|
|
||||||
*/
|
|
||||||
default void setDebugMode(boolean enable) {
|
|
||||||
setDebugMode(() -> enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取调试处理器,用于处理调试信息。
|
|
||||||
*
|
|
||||||
* @return {@link SQLDebugHandler}
|
|
||||||
*/
|
|
||||||
@NotNull SQLDebugHandler getDebugHandler();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定调试处理器,默认为 {@link SQLDebugHandler#defaultHandler(Logger)} 。
|
|
||||||
*
|
|
||||||
* @param debugHandler {@link SQLDebugHandler}
|
|
||||||
*/
|
|
||||||
void setDebugHandler(@NotNull SQLDebugHandler debugHandler);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到连接池源
|
|
||||||
*
|
|
||||||
* @return DataSource
|
|
||||||
*/
|
|
||||||
@NotNull DataSource getDataSource();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到一个数据库连接实例
|
|
||||||
*
|
|
||||||
* @return Connection
|
|
||||||
* @throws SQLException 见 {@link DataSource#getConnection()}
|
|
||||||
*/
|
|
||||||
@NotNull Connection getConnection() throws SQLException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到正使用的查询。
|
|
||||||
*
|
|
||||||
* @return 查询列表
|
|
||||||
*/
|
|
||||||
@NotNull Map<UUID, SQLQuery> getActiveQuery();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取改管理器提供的默认异常处理器。
|
|
||||||
* 若未使用过 {@link #setExceptionHandler(SQLExceptionHandler)} 方法,
|
|
||||||
* 则默认返回 {@link SQLExceptionHandler#detailed(Logger)} 。
|
|
||||||
*
|
|
||||||
* @return {@link SQLExceptionHandler}
|
|
||||||
*/
|
|
||||||
@NotNull SQLExceptionHandler getExceptionHandler();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定通用的异常处理器。
|
|
||||||
* <br> 在使用 {@link SQLAction#execute(SQLExceptionHandler)} 等相关方法时,若传入的处理器为null,则会采用此处理器。
|
|
||||||
* <br> 若该方法传入参数为 null,则会使用 {@link SQLExceptionHandler#detailed(Logger)} 。
|
|
||||||
*
|
|
||||||
* @param handler 异常处理器
|
|
||||||
*/
|
|
||||||
void setExceptionHandler(@Nullable SQLExceptionHandler handler);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行一条不需要返回结果的SQL语句(多用于UPDATE、REPLACE、DELETE方法)
|
|
||||||
* 该方法使用 Statement 实现,请注意SQL注入风险!
|
|
||||||
*
|
|
||||||
* @param sql SQL语句内容
|
|
||||||
* @return 更新的行数
|
|
||||||
* @see SQLUpdateAction
|
|
||||||
*/
|
|
||||||
@Nullable Integer executeSQL(String sql);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行一条不需要返回结果的预处理SQL更改(UPDATE、REPLACE、DELETE)
|
|
||||||
*
|
|
||||||
* @param sql SQL语句内容
|
|
||||||
* @param params SQL语句中 ? 的对应参数
|
|
||||||
* @return 更新的行数
|
|
||||||
* @see PreparedSQLUpdateAction
|
|
||||||
*/
|
|
||||||
@Nullable Integer executeSQL(String sql, Object[] params);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行多条不需要返回结果的SQL更改(UPDATE、REPLACE、DELETE)
|
|
||||||
*
|
|
||||||
* @param sql SQL语句内容
|
|
||||||
* @param paramsBatch SQL语句中对应?的参数组
|
|
||||||
* @return 对应参数返回的行数
|
|
||||||
* @see PreparedSQLUpdateBatchAction
|
|
||||||
*/
|
|
||||||
@Nullable List<Integer> executeSQLBatch(String sql, Iterable<Object[]> paramsBatch);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行多条不需要返回结果的SQL。
|
|
||||||
* 该方法使用 Statement 实现,请注意SQL注入风险!
|
|
||||||
*
|
|
||||||
* @param sql SQL语句内容
|
|
||||||
* @param moreSQL 更多SQL语句内容
|
|
||||||
* @return 对应参数返回的行数
|
|
||||||
* @see SQLUpdateBatchAction
|
|
||||||
*/
|
|
||||||
@Nullable List<Integer> executeSQLBatch(@NotNull String sql, String... moreSQL);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行多条不需要返回结果的SQL。
|
|
||||||
*
|
|
||||||
* @param sqlBatch SQL语句内容
|
|
||||||
* @return 对应参数返回的行数
|
|
||||||
*/
|
|
||||||
@Nullable List<Integer> executeSQLBatch(@NotNull Iterable<String> sqlBatch);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取并操作 {@link DatabaseMetaData} 以得到需要的数据库消息。
|
|
||||||
*
|
|
||||||
* @param reader 操作与读取的方法
|
|
||||||
* @param <R> 最终结果的返回类型
|
|
||||||
* @return 最终结果,通过 {@link CompletableFuture#get()} 可阻塞并等待结果返回。
|
|
||||||
*/
|
|
||||||
default <R> CompletableFuture<R> fetchMetadata(@NotNull SQLFunction<DatabaseMetaData, R> reader) {
|
|
||||||
return fetchMetadata((meta, conn) -> reader.apply(meta));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取并操作 {@link DatabaseMetaData} 提供的指定 {@link ResultSet} 以得到需要的数据库消息。
|
|
||||||
* <br> 该方法会自动关闭 {@link ResultSet} 。
|
|
||||||
*
|
|
||||||
* @param supplier 操作 {@link DatabaseMetaData} 以提供信息所在的 {@link ResultSet}
|
|
||||||
* @param reader 读取 {@link ResultSet} 中指定信息的方法
|
|
||||||
* @param <R> 最终结果的返回类型
|
|
||||||
* @return 最终结果,通过 {@link CompletableFuture#get()} 可阻塞并等待结果返回。
|
|
||||||
* @throws NullPointerException 当 supplier 提供的 {@link ResultSet} 为NULL时抛出
|
|
||||||
*/
|
|
||||||
default <R> CompletableFuture<R> fetchMetadata(@NotNull SQLFunction<DatabaseMetaData, ResultSet> supplier,
|
|
||||||
@NotNull SQLFunction<@NotNull ResultSet, R> reader) {
|
|
||||||
return fetchMetadata((meta, conn) -> supplier.apply(meta), reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取并操作 {@link DatabaseMetaData} 以得到需要的数据库消息。
|
|
||||||
*
|
|
||||||
* @param reader 操作与读取的方法
|
|
||||||
* @param <R> 最终结果的返回类型
|
|
||||||
* @return 最终结果,通过 {@link CompletableFuture#get()} 可阻塞并等待结果返回。
|
|
||||||
*/
|
|
||||||
<R> CompletableFuture<R> fetchMetadata(@NotNull SQLBiFunction<DatabaseMetaData, Connection, R> reader);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取并操作 {@link DatabaseMetaData} 提供的指定 {@link ResultSet} 以得到需要的数据库消息。
|
|
||||||
* <br> 该方法会自动关闭 {@link ResultSet} 。
|
|
||||||
*
|
|
||||||
* @param supplier 操作 {@link DatabaseMetaData} 以提供信息所在的 {@link ResultSet}
|
|
||||||
* @param reader 读取 {@link ResultSet} 中指定信息的方法
|
|
||||||
* @param <R> 最终结果的返回类型
|
|
||||||
* @return 最终结果,通过 {@link CompletableFuture#get()} 可阻塞并等待结果返回。
|
|
||||||
* @throws NullPointerException 当 supplier 提供的 {@link ResultSet} 为NULL时抛出
|
|
||||||
*/
|
|
||||||
<R> CompletableFuture<R> fetchMetadata(@NotNull SQLBiFunction<DatabaseMetaData, Connection, ResultSet> supplier,
|
|
||||||
@NotNull SQLFunction<@NotNull ResultSet, R> reader);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 在库中创建一个表。
|
|
||||||
*
|
|
||||||
* @param tableName 表名
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
TableCreateBuilder createTable(@NotNull String tableName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 对库中的某个表执行更改。
|
|
||||||
*
|
|
||||||
* @param tableName 表名
|
|
||||||
* @return {@link TableAlterBuilder}
|
|
||||||
*/
|
|
||||||
TableAlterBuilder alterTable(@NotNull String tableName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 快速获取表的部分元数据。
|
|
||||||
* <br> 当需要获取其他元数据时,请使用 {@link #fetchMetadata(SQLFunction, SQLFunction)} 方法。
|
|
||||||
*
|
|
||||||
* @param tablePattern 表名通配符
|
|
||||||
* @return {@link TableMetadataBuilder}
|
|
||||||
*/
|
|
||||||
TableMetadataBuilder fetchTableMetadata(@NotNull String tablePattern);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新建一个查询。
|
|
||||||
*
|
|
||||||
* @return {@link QueryBuilder}
|
|
||||||
*/
|
|
||||||
QueryBuilder createQuery();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建一条插入操作。
|
|
||||||
*
|
|
||||||
* @param tableName 目标表名
|
|
||||||
* @return {@link InsertBuilder}
|
|
||||||
*/
|
|
||||||
InsertBuilder<PreparedSQLUpdateAction<Integer>> createInsert(@NotNull String tableName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建支持多组数据的插入操作。
|
|
||||||
*
|
|
||||||
* @param tableName 目标表名
|
|
||||||
* @return {@link InsertBuilder}
|
|
||||||
*/
|
|
||||||
InsertBuilder<PreparedSQLUpdateBatchAction<Integer>> createInsertBatch(@NotNull String tableName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建一条替换操作。
|
|
||||||
*
|
|
||||||
* @param tableName 目标表名
|
|
||||||
* @return {@link ReplaceBuilder}
|
|
||||||
*/
|
|
||||||
ReplaceBuilder<PreparedSQLUpdateAction<Integer>> createReplace(@NotNull String tableName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建支持多组数据的替换操作。
|
|
||||||
*
|
|
||||||
* @param tableName 目标表名
|
|
||||||
* @return {@link ReplaceBuilder}
|
|
||||||
*/
|
|
||||||
ReplaceBuilder<PreparedSQLUpdateBatchAction<Integer>> createReplaceBatch(@NotNull String tableName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建更新操作。
|
|
||||||
*
|
|
||||||
* @param tableName 目标表名
|
|
||||||
* @return {@link UpdateBuilder}
|
|
||||||
*/
|
|
||||||
UpdateBuilder createUpdate(@NotNull String tableName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建删除操作。
|
|
||||||
*
|
|
||||||
* @param tableName 目标表名
|
|
||||||
* @return {@link DeleteBuilder}
|
|
||||||
*/
|
|
||||||
DeleteBuilder createDelete(@NotNull String tableName);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.query.PreparedQueryAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.query.QueryAction;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SQLQuery 是一个查询中间接口,用于查询操作的封装。
|
|
||||||
*
|
|
||||||
* @author CarmJos
|
|
||||||
*/
|
|
||||||
public interface SQLQuery extends AutoCloseable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取该查询创建的时间
|
|
||||||
* <br>注意,此处获得的时间非时间戳毫秒数,仅用于计算耗时。
|
|
||||||
*
|
|
||||||
* @return 创建时间
|
|
||||||
*/
|
|
||||||
default long getExecuteTime() {
|
|
||||||
return getExecuteTime(TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取该查询创建的时间
|
|
||||||
* <br>注意,此处获得的时间非时间戳毫秒数,仅用于计算耗时。
|
|
||||||
*
|
|
||||||
* @param timeUnit 时间单位
|
|
||||||
* @return 创建时间
|
|
||||||
*/
|
|
||||||
long getExecuteTime(TimeUnit timeUnit);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到承载该SQLQuery的对应{@link SQLManager}
|
|
||||||
*
|
|
||||||
* @return {@link SQLManager}
|
|
||||||
*/
|
|
||||||
SQLManager getManager();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到承载该SQLQuery的对应{@link QueryAction}
|
|
||||||
*
|
|
||||||
* @return {@link QueryAction} 或 {@link PreparedQueryAction}
|
|
||||||
*/
|
|
||||||
QueryAction getAction();
|
|
||||||
|
|
||||||
ResultSet getResultSet();
|
|
||||||
|
|
||||||
default boolean containsResult(String columnName) throws SQLException {
|
|
||||||
return getResultSet() != null && getResultSet().getObject(columnName) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到设定的SQL语句
|
|
||||||
*
|
|
||||||
* @return SQL语句
|
|
||||||
*/
|
|
||||||
String getSQLContent();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 关闭所有内容
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
void close();
|
|
||||||
|
|
||||||
Statement getStatement();
|
|
||||||
|
|
||||||
Connection getConnection();
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,149 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.PreparedSQLUpdateAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.PreparedSQLUpdateBatchAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.builder.*;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLHandler;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.table.NamedSQLTable;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SQLTable 基于 {@link TableCreateBuilder} 构建表,用于快速创建与该表相关的操作。
|
|
||||||
* <ul>
|
|
||||||
* <li>1. 调用 {@link NamedSQLTable#of(String, String[])} 方法创建一个 SQLTable 对象;</li>
|
|
||||||
* <li>2. 在应用初始化阶段调用 {@link NamedSQLTable#create(SQLManager)} 方法初始化 SQLTable 对象;</li>
|
|
||||||
* <li>3. 获取已创建的{@link NamedSQLTable} 实例,直接调用对应方法进行关于表的相关操作。</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @author CarmJos
|
|
||||||
* @since 0.3.10
|
|
||||||
*/
|
|
||||||
public interface SQLTable {
|
|
||||||
|
|
||||||
static @NotNull NamedSQLTable of(@NotNull String tableName, @Nullable SQLHandler<TableCreateBuilder> table) {
|
|
||||||
return new NamedSQLTable(tableName) {
|
|
||||||
@Override
|
|
||||||
public boolean create(@NotNull SQLManager sqlManager, String tablePrefix) throws SQLException {
|
|
||||||
if (this.manager == null) this.manager = sqlManager;
|
|
||||||
this.tablePrefix = tablePrefix;
|
|
||||||
|
|
||||||
TableCreateBuilder tableBuilder = sqlManager.createTable(getTableName());
|
|
||||||
if (table != null) table.accept(tableBuilder);
|
|
||||||
return tableBuilder.build().executeFunction(l -> l > 0, false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static @NotNull NamedSQLTable of(@NotNull String tableName, @NotNull String[] columns) {
|
|
||||||
return of(tableName, columns, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
static @NotNull NamedSQLTable of(@NotNull String tableName,
|
|
||||||
@NotNull String[] columns, @Nullable String tableSettings) {
|
|
||||||
return of(tableName, builder -> {
|
|
||||||
builder.setColumns(columns);
|
|
||||||
if (tableSettings != null) builder.setTableSettings(tableSettings);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 以指定的 {@link SQLManager} 实例初始化并创建该表
|
|
||||||
*
|
|
||||||
* @param sqlManager {@link SQLManager} 实例
|
|
||||||
* @return 是否新创建了本表 (若已创建或创建失败则返回false)
|
|
||||||
* @throws SQLException 当数据库返回异常时抛出
|
|
||||||
*/
|
|
||||||
boolean create(SQLManager sqlManager) throws SQLException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到 {@link #create(SQLManager)} 用于初始化本实例的 {@link SQLManager} 实例
|
|
||||||
*
|
|
||||||
* @return {@link SQLManager} 实例
|
|
||||||
*/
|
|
||||||
@Nullable SQLManager getSQLManager();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到本表表名,不得为空。
|
|
||||||
*
|
|
||||||
* @return 本表表名
|
|
||||||
*/
|
|
||||||
@NotNull String getTableName();
|
|
||||||
|
|
||||||
default @NotNull TableQueryBuilder createQuery() {
|
|
||||||
return Optional.ofNullable(getSQLManager()).map(this::createQuery)
|
|
||||||
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
|
|
||||||
}
|
|
||||||
|
|
||||||
default @NotNull TableQueryBuilder createQuery(@NotNull SQLManager sqlManager) {
|
|
||||||
return sqlManager.createQuery().inTable(getTableName());
|
|
||||||
}
|
|
||||||
|
|
||||||
default @NotNull DeleteBuilder createDelete() {
|
|
||||||
return Optional.ofNullable(getSQLManager()).map(this::createDelete)
|
|
||||||
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
|
|
||||||
}
|
|
||||||
|
|
||||||
default @NotNull DeleteBuilder createDelete(@NotNull SQLManager sqlManager) {
|
|
||||||
return sqlManager.createDelete(getTableName());
|
|
||||||
}
|
|
||||||
|
|
||||||
default @NotNull UpdateBuilder createUpdate() {
|
|
||||||
return Optional.ofNullable(getSQLManager()).map(this::createUpdate)
|
|
||||||
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
|
|
||||||
}
|
|
||||||
|
|
||||||
default @NotNull UpdateBuilder createUpdate(@NotNull SQLManager sqlManager) {
|
|
||||||
return sqlManager.createUpdate(getTableName());
|
|
||||||
}
|
|
||||||
|
|
||||||
default @NotNull InsertBuilder<PreparedSQLUpdateAction<Integer>> createInsert() {
|
|
||||||
return Optional.ofNullable(getSQLManager()).map(this::createInsert)
|
|
||||||
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
|
|
||||||
}
|
|
||||||
|
|
||||||
default @NotNull InsertBuilder<PreparedSQLUpdateAction<Integer>> createInsert(@NotNull SQLManager sqlManager) {
|
|
||||||
return sqlManager.createInsert(getTableName());
|
|
||||||
}
|
|
||||||
|
|
||||||
default @NotNull InsertBuilder<PreparedSQLUpdateBatchAction<Integer>> createInsertBatch() {
|
|
||||||
return Optional.ofNullable(getSQLManager()).map(this::createInsertBatch)
|
|
||||||
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
|
|
||||||
}
|
|
||||||
|
|
||||||
default @NotNull InsertBuilder<PreparedSQLUpdateBatchAction<Integer>> createInsertBatch(@NotNull SQLManager sqlManager) {
|
|
||||||
return sqlManager.createInsertBatch(getTableName());
|
|
||||||
}
|
|
||||||
|
|
||||||
default @NotNull ReplaceBuilder<PreparedSQLUpdateAction<Integer>> createReplace() {
|
|
||||||
return Optional.ofNullable(getSQLManager()).map(this::createReplace)
|
|
||||||
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
default @NotNull ReplaceBuilder<PreparedSQLUpdateAction<Integer>> createReplace(@NotNull SQLManager sqlManager) {
|
|
||||||
return sqlManager.createReplace(getTableName());
|
|
||||||
}
|
|
||||||
|
|
||||||
default @NotNull ReplaceBuilder<PreparedSQLUpdateBatchAction<Integer>> createReplaceBatch() {
|
|
||||||
return Optional.ofNullable(getSQLManager()).map(this::createReplaceBatch)
|
|
||||||
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
|
|
||||||
}
|
|
||||||
|
|
||||||
default @NotNull ReplaceBuilder<PreparedSQLUpdateBatchAction<Integer>> createReplaceBatch(@NotNull SQLManager sqlManager) {
|
|
||||||
return sqlManager.createReplaceBatch(getTableName());
|
|
||||||
}
|
|
||||||
|
|
||||||
default @NotNull TableAlterBuilder alter() {
|
|
||||||
return Optional.ofNullable(getSQLManager()).map(this::alter)
|
|
||||||
.orElseThrow(() -> new NullPointerException("This table doesn't have a SQLManger."));
|
|
||||||
}
|
|
||||||
|
|
||||||
default @NotNull TableAlterBuilder alter(@NotNull SQLManager sqlManager) {
|
|
||||||
return sqlManager.alterTable(getTableName());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.action;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
public interface PreparedSQLUpdateAction<T extends Number> extends SQLUpdateAction<T> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定SQL语句中所有 ? 对应的参数
|
|
||||||
*
|
|
||||||
* @param params 参数内容
|
|
||||||
* @return {@link PreparedSQLUpdateAction}
|
|
||||||
*/
|
|
||||||
PreparedSQLUpdateAction<T> setParams(Object... params);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定SQL语句中所有 ? 对应的参数
|
|
||||||
*
|
|
||||||
* @param params 参数内容
|
|
||||||
* @return {@link PreparedSQLUpdateAction}
|
|
||||||
* @since 0.4.0
|
|
||||||
*/
|
|
||||||
PreparedSQLUpdateAction<T> setParams(@Nullable Iterable<Object> params);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.action;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface PreparedSQLUpdateBatchAction<T extends Number> extends SQLAction<List<T>> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定多组SQL语句中所有 ? 对应的参数
|
|
||||||
*
|
|
||||||
* @param allParams 所有参数内容
|
|
||||||
* @return {@link PreparedSQLUpdateBatchAction}
|
|
||||||
*/
|
|
||||||
PreparedSQLUpdateBatchAction<T> setAllParams(Iterable<Object[]> allParams);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加一组SQL语句中所有 ? 对应的参数
|
|
||||||
*
|
|
||||||
* @param params 参数内容
|
|
||||||
* @return {@link PreparedSQLUpdateBatchAction}
|
|
||||||
*/
|
|
||||||
PreparedSQLUpdateBatchAction<T> addParamsBatch(Object... params);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定该操作返回自增键序列。
|
|
||||||
*
|
|
||||||
* @return {@link SQLUpdateAction}
|
|
||||||
*/
|
|
||||||
PreparedSQLUpdateBatchAction<T> returnGeneratedKeys();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定该操作返回自增键序列。
|
|
||||||
*
|
|
||||||
* @param keyTypeClass 自增序列的数字类型
|
|
||||||
* @param <N> 自增键序列类型 {@link Number}
|
|
||||||
* @return {@link SQLUpdateAction}
|
|
||||||
* @since 0.4.0
|
|
||||||
*/
|
|
||||||
<N extends Number> PreparedSQLUpdateBatchAction<N> returnGeneratedKeys(Class<N> keyTypeClass);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.action;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
|
|
||||||
public interface SQLUpdateAction<T extends Number> extends SQLAction<T> {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定该操作返回自增键序列。
|
|
||||||
*
|
|
||||||
* @return {@link SQLUpdateAction}
|
|
||||||
*/
|
|
||||||
SQLUpdateAction<T> returnGeneratedKey();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定该操作返回自增键序列。
|
|
||||||
*
|
|
||||||
* @param keyTypeClass 自增序列的数字类型
|
|
||||||
* @param <N> 自增键序列类型 {@link Number}
|
|
||||||
* @return {@link SQLUpdateAction}
|
|
||||||
* @since 0.4.0
|
|
||||||
*/
|
|
||||||
<N extends Number> SQLUpdateAction<N> returnGeneratedKey(Class<N> keyTypeClass);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.action;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@SuppressWarnings("UnusedReturnValue")
|
|
||||||
public interface SQLUpdateBatchAction extends SQLAction<List<Integer>> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加一条批量执行的SQL语句
|
|
||||||
*
|
|
||||||
* @param sql SQL语句
|
|
||||||
* @return {@link SQLUpdateBatchAction}
|
|
||||||
*/
|
|
||||||
SQLUpdateBatchAction addBatch(@NotNull String sql);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default @NotNull String getSQLContent() {
|
|
||||||
return getSQLContents().get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull List<String> getSQLContents();
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.action.query;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public interface PreparedQueryAction extends QueryAction {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定SQL语句中所有 ? 对应的参数
|
|
||||||
*
|
|
||||||
* @param params 参数内容
|
|
||||||
* @return {@link PreparedQueryAction}
|
|
||||||
*/
|
|
||||||
PreparedQueryAction setParams(@Nullable Object... params);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定SQL语句中所有 ? 对应的参数
|
|
||||||
*
|
|
||||||
* @param params 参数内容
|
|
||||||
* @return {@link PreparedQueryAction}
|
|
||||||
*/
|
|
||||||
PreparedQueryAction setParams(@Nullable Iterable<Object> params);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 直接对 {@link PreparedStatement} 进行处理
|
|
||||||
*
|
|
||||||
* @param statement {@link Consumer} 处理操作
|
|
||||||
* 若为空则不进行处理
|
|
||||||
* @return {@link PreparedQueryAction}
|
|
||||||
*/
|
|
||||||
PreparedQueryAction handleStatement(@Nullable Consumer<PreparedStatement> statement);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.action.query;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLQuery;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLExceptionHandler;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLFunction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLHandler;
|
|
||||||
import org.jetbrains.annotations.Contract;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SQLQueryAction 是用于承载SQL查询语句并进行处理、返回并自动关闭连接的基本类。
|
|
||||||
*
|
|
||||||
* <ul>
|
|
||||||
* <li>同步执行 {@link #execute()}, {@link #execute(SQLFunction, SQLExceptionHandler)}
|
|
||||||
* <br>同步执行方法中有会抛出异常的方法与不抛出异常的方法,
|
|
||||||
* <br>若选择不抛出异常,则返回值可能为空,需要特殊处理。</li>
|
|
||||||
*
|
|
||||||
* <li>异步执行 {@link #executeAsync(SQLHandler, SQLExceptionHandler)}
|
|
||||||
* <br>异步执行时将提供成功与异常两种处理方式
|
|
||||||
* <br>可自行选择是否对数据或异常进行处理
|
|
||||||
* <br>默认的异常处理器为 {@link #defaultExceptionHandler()}</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* <b>注意: 无论是否异步,都不需要自行关闭ResultSet,本API已自动关闭</b>
|
|
||||||
*
|
|
||||||
* @author CarmJos
|
|
||||||
* @since 0.2.6
|
|
||||||
*/
|
|
||||||
public interface QueryAction extends SQLAction<SQLQuery> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Contract("_,!null -> !null")
|
|
||||||
default <R> @Nullable R executeFunction(@NotNull SQLFunction<@NotNull SQLQuery, R> function,
|
|
||||||
@Nullable R defaultResult) throws SQLException {
|
|
||||||
try (SQLQuery value = execute()) {
|
|
||||||
R result = function.apply(value);
|
|
||||||
return result == null ? defaultResult : result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.builder;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLBuilder;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
|
|
||||||
public interface ConditionalBuilder<B extends ConditionalBuilder<B, T>, T extends SQLAction<?>> extends SQLBuilder {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将现有条件构建完整的SQL语句用于执行。
|
|
||||||
*
|
|
||||||
* @return {@link SQLAction}
|
|
||||||
*/
|
|
||||||
T build();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定限定的条目数
|
|
||||||
*
|
|
||||||
* @param limit 条数限制
|
|
||||||
* @return {@link B}
|
|
||||||
*/
|
|
||||||
B setLimit(int limit);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 直接设定条件的源文本,不需要以WHERE开头。
|
|
||||||
* <br>如 {@code id = 1 AND name = 'test' OR name = 'test2'} 。
|
|
||||||
*
|
|
||||||
* @param condition 条件文本,不需要以WHERE开头。
|
|
||||||
* @return {@link B}
|
|
||||||
*/
|
|
||||||
B setConditions(@Nullable String condition);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 直接设定每个条件的文本与其对应数值,将以AND链接,且不需要以WHERE开头。
|
|
||||||
* <br>条件如 {@code id = ? },问号将被以对应的数值填充。。
|
|
||||||
*
|
|
||||||
* @param conditionSQLs 条件内容,将以AND链接,且不需要以WHERE开头。
|
|
||||||
* @return {@link B}
|
|
||||||
*/
|
|
||||||
B setConditions(LinkedHashMap<@NotNull String, @Nullable Object> conditionSQLs);
|
|
||||||
|
|
||||||
B addCondition(@Nullable String condition);
|
|
||||||
|
|
||||||
B addCondition(@NotNull String columnName, @NotNull String operator, @Nullable Object queryValue);
|
|
||||||
|
|
||||||
B addCondition(@NotNull String columnName, @Nullable Object queryValue);
|
|
||||||
|
|
||||||
B addCondition(@NotNull String[] columnNames, @Nullable Object[] queryValues);
|
|
||||||
|
|
||||||
B addNotNullCondition(@NotNull String columnName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加时间的限定条件。 若设定了开始时间,则限定条件为 {@code endMillis >= startMillis};
|
|
||||||
*
|
|
||||||
* @param columnName 判断的行
|
|
||||||
* @param startMillis 开始时间戳,若{@code <0}则不作限定
|
|
||||||
* @param endMillis 结束时间戳,若{@code <0}则不作限定
|
|
||||||
* @return {@link B}
|
|
||||||
*/
|
|
||||||
default B addTimeCondition(@NotNull String columnName, long startMillis, long endMillis) {
|
|
||||||
return addTimeCondition(columnName,
|
|
||||||
startMillis > 0 ? new Date(startMillis) : null,
|
|
||||||
endMillis > 0 ? new Date(endMillis) : null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加时间的限定条件。 若设定了开始时间,则限定条件为 {@code endDate >= startTime};
|
|
||||||
*
|
|
||||||
* @param columnName 判断的行
|
|
||||||
* @param startDate 开始时间,若为null则不作限定
|
|
||||||
* @param endDate 结束时间,若为null则不作限定
|
|
||||||
* @return {@link B}
|
|
||||||
*/
|
|
||||||
B addTimeCondition(@NotNull String columnName, @Nullable Date startDate, @Nullable Date endDate);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.builder;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
|
|
||||||
public interface DeleteBuilder extends ConditionalBuilder<DeleteBuilder, SQLAction<Integer>> {
|
|
||||||
|
|
||||||
String getTableName();
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.builder;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface InsertBuilder<T extends SQLAction<?>> {
|
|
||||||
|
|
||||||
String getTableName();
|
|
||||||
|
|
||||||
boolean isIgnore();
|
|
||||||
|
|
||||||
InsertBuilder<T> setIgnore(boolean ignore);
|
|
||||||
|
|
||||||
T setColumnNames(List<String> columnNames);
|
|
||||||
|
|
||||||
default T setColumnNames(String... columnNames) {
|
|
||||||
return setColumnNames(columnNames == null ? null : Arrays.asList(columnNames));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.builder;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.query.PreparedQueryAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.query.QueryAction;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public interface QueryBuilder extends SQLBuilder {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过一条 SQL语句创建查询。
|
|
||||||
* 该方法使用 Statement 实现,请注意SQL注入风险!
|
|
||||||
*
|
|
||||||
* @param sql SQL语句
|
|
||||||
* @return {@link QueryAction}
|
|
||||||
* @deprecated 存在SQL注入风险,建议使用 {@link QueryBuilder#withPreparedSQL(String)}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
QueryAction withSQL(@NotNull String sql);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过一条 SQL语句创建预查询
|
|
||||||
*
|
|
||||||
* @param sql SQL语句
|
|
||||||
* @return {@link PreparedQueryAction}
|
|
||||||
*/
|
|
||||||
PreparedQueryAction withPreparedSQL(@NotNull String sql);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建表查询
|
|
||||||
*
|
|
||||||
* @param tableName 表名
|
|
||||||
* @return {@link TableQueryBuilder}
|
|
||||||
*/
|
|
||||||
TableQueryBuilder inTable(@NotNull String tableName);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.builder;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* REPLACE 语句用于将一组值更新进数据表中。
|
|
||||||
* <br> 执行后,将通过表中键判断该数据是否存在,若存在则用新数据替换原来的值,若不存在则会插入该数据。
|
|
||||||
* <br> 在使用REPLACE时,表与所给行列数据中必须包含唯一索引(或主键),且索引不得为空值,否则将等同于插入语句。
|
|
||||||
*
|
|
||||||
* @param <T> 最终构建出的 {@link SQLAction} 类型
|
|
||||||
*/
|
|
||||||
public interface ReplaceBuilder<T extends SQLAction<?>> {
|
|
||||||
|
|
||||||
String getTableName();
|
|
||||||
|
|
||||||
T setColumnNames(List<String> columnNames);
|
|
||||||
|
|
||||||
default T setColumnNames(String... columnNames) {
|
|
||||||
return setColumnNames(columnNames == null ? null : Arrays.asList(columnNames));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,129 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.builder;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.SQLUpdateAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.enums.IndexType;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.enums.NumberType;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
public interface TableAlterBuilder extends SQLBuilder {
|
|
||||||
|
|
||||||
SQLAction<Integer> renameTo(@NotNull String newTableName);
|
|
||||||
|
|
||||||
SQLAction<Integer> changeComment(@NotNull String newTableComment);
|
|
||||||
|
|
||||||
SQLAction<Integer> setAutoIncrementIndex(int index);
|
|
||||||
|
|
||||||
SQLAction<Integer> addIndex(@NotNull IndexType indexType, @Nullable String indexName,
|
|
||||||
@NotNull String columnName, @NotNull String... moreColumns);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为该表移除一个索引
|
|
||||||
*
|
|
||||||
* @param indexName 索引名
|
|
||||||
* @return {@link SQLUpdateAction}
|
|
||||||
*/
|
|
||||||
SQLAction<Integer> dropIndex(@NotNull String indexName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为该表移除一个外键
|
|
||||||
*
|
|
||||||
* @param keySymbol 外键名
|
|
||||||
* @return {@link SQLUpdateAction}
|
|
||||||
*/
|
|
||||||
SQLAction<Integer> dropForeignKey(@NotNull String keySymbol);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为该表移除主键(须添加新主键)
|
|
||||||
*
|
|
||||||
* @return {@link SQLUpdateAction}
|
|
||||||
*/
|
|
||||||
SQLAction<Integer> dropPrimaryKey();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为表添加一列
|
|
||||||
*
|
|
||||||
* @param columnName 列名
|
|
||||||
* @param settings 列的相关设定
|
|
||||||
* @return {@link SQLUpdateAction}
|
|
||||||
*/
|
|
||||||
default SQLAction<Integer> addColumn(@NotNull String columnName, @NotNull String settings) {
|
|
||||||
return addColumn(columnName, settings, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为表添加一列
|
|
||||||
*
|
|
||||||
* @param columnName 列名
|
|
||||||
* @param settings 列的相关设定
|
|
||||||
* @param afterColumn 该列增添到哪个列的后面,
|
|
||||||
* <p> 该参数若省缺则放于最后一行
|
|
||||||
* <p> 若为 "" 则置于首行。
|
|
||||||
* @return {@link SQLUpdateAction}
|
|
||||||
*/
|
|
||||||
SQLAction<Integer> addColumn(@NotNull String columnName, @NotNull String settings, @Nullable String afterColumn);
|
|
||||||
|
|
||||||
SQLAction<Integer> renameColumn(@NotNull String columnName, @NotNull String newName);
|
|
||||||
|
|
||||||
SQLAction<Integer> modifyColumn(@NotNull String columnName, @NotNull String settings);
|
|
||||||
|
|
||||||
default SQLAction<Integer> modifyColumn(@NotNull String columnName, @NotNull String columnSettings, @NotNull String afterColumn) {
|
|
||||||
return modifyColumn(columnName, columnSettings + " AFTER `" + afterColumn + "`");
|
|
||||||
}
|
|
||||||
|
|
||||||
SQLAction<Integer> removeColumn(@NotNull String columnName);
|
|
||||||
|
|
||||||
SQLAction<Integer> setColumnDefault(@NotNull String columnName, @NotNull String defaultValue);
|
|
||||||
|
|
||||||
SQLAction<Integer> removeColumnDefault(@NotNull String columnName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为该表添加一个自增列
|
|
||||||
* <p> 自增列强制要求为数字类型,非空,且为UNIQUE。
|
|
||||||
* <p> 注意:一个表只允许有一个自增列!
|
|
||||||
*
|
|
||||||
* @param columnName 列名
|
|
||||||
* @param numberType 数字类型,若省缺则为 {@link NumberType#INT}
|
|
||||||
* @param primary 是否为主键,若否则只为唯一键
|
|
||||||
* @param unsigned 是否采用 UNSIGNED (即无负数,可以增加自增键的最高数,建议为true)
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
default SQLAction<Integer> addAutoIncrementColumn(@NotNull String columnName, @Nullable NumberType numberType,
|
|
||||||
boolean primary, boolean unsigned) {
|
|
||||||
return addColumn(columnName,
|
|
||||||
(numberType == null ? NumberType.INT : numberType).name()
|
|
||||||
+ (unsigned ? " UNSIGNED " : " ")
|
|
||||||
+ "NOT NULL AUTO_INCREMENT " + (primary ? "PRIMARY KEY" : "UNIQUE KEY"),
|
|
||||||
""
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为该表添加一个自增列
|
|
||||||
* <br> 自增列强制要求为数字类型,非空,且为UNIQUE。
|
|
||||||
* <p> 注意:一个表只允许有一个自增列!
|
|
||||||
*
|
|
||||||
* @param columnName 列名
|
|
||||||
* @param numberType 数字类型,若省缺则为 {@link NumberType#INT}
|
|
||||||
* @return {@link TableAlterBuilder}
|
|
||||||
*/
|
|
||||||
default SQLAction<Integer> addAutoIncrementColumn(@NotNull String columnName, @NotNull NumberType numberType) {
|
|
||||||
return addAutoIncrementColumn(columnName, numberType, false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为该表添加一个自增列
|
|
||||||
* <br> 自增列强制要求为数字类型,非空,且为UNIQUE。
|
|
||||||
* <p> 注意:一个表只允许有一个自增列!
|
|
||||||
*
|
|
||||||
* @param columnName 列名
|
|
||||||
* @return {@link TableAlterBuilder}
|
|
||||||
*/
|
|
||||||
default SQLAction<Integer> addAutoIncrementColumn(@NotNull String columnName) {
|
|
||||||
return addAutoIncrementColumn(columnName, NumberType.INT);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,256 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.builder;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.SQLUpdateAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.enums.ForeignKeyRule;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.enums.IndexType;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.enums.NumberType;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import static com.io.yutian.elementoriginlib.sql.api.SQLBuilder.withBackQuote;
|
|
||||||
import static com.io.yutian.elementoriginlib.sql.api.SQLBuilder.withQuote;
|
|
||||||
|
|
||||||
|
|
||||||
public interface TableCreateBuilder extends SQLBuilder {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将现有条件构建完整的SQL语句用于执行。
|
|
||||||
*
|
|
||||||
* @return {@link SQLUpdateAction}
|
|
||||||
*/
|
|
||||||
SQLUpdateAction<Integer> build();
|
|
||||||
|
|
||||||
@NotNull String getTableName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到表的设定。
|
|
||||||
* <p> 若未使用 {@link #setTableSettings(String)} 方法则会采用 {@link #defaultTablesSettings()} 。
|
|
||||||
*
|
|
||||||
* @return TableSettings
|
|
||||||
*/
|
|
||||||
@NotNull String getTableSettings();
|
|
||||||
|
|
||||||
TableCreateBuilder setTableSettings(@NotNull String settings);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定表的标注,一般用于解释该表的作用。
|
|
||||||
*
|
|
||||||
* @param comment 表标注
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
TableCreateBuilder setTableComment(@Nullable String comment);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 直接设定表的所有列信息
|
|
||||||
*
|
|
||||||
* @param columns 列的相关信息 (包括列设定)
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
TableCreateBuilder setColumns(@NotNull String... columns);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为该表添加一个列
|
|
||||||
*
|
|
||||||
* @param column 列的相关信息
|
|
||||||
* <br>如 `uuid` VARCHAR(36) NOT NULL UNIQUE KEY
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
TableCreateBuilder addColumn(@NotNull String column);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为该表添加一个列
|
|
||||||
*
|
|
||||||
* @param columnName 列名
|
|
||||||
* @param settings 列的设定
|
|
||||||
* <br>如 VARCHAR(36) NOT NULL UNIQUE KEY
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
default TableCreateBuilder addColumn(@NotNull String columnName, @NotNull String settings) {
|
|
||||||
Objects.requireNonNull(columnName, "columnName could not be null");
|
|
||||||
return addColumn(withBackQuote(columnName) + " " + settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为该表添加一个列
|
|
||||||
*
|
|
||||||
* @param columnName 列名
|
|
||||||
* @param settings 列的设定
|
|
||||||
* <br>如 VARCHAR(36) NOT NULL UNIQUE KEY
|
|
||||||
* @param comments 列的注解,用于解释该列数据的作用
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
default TableCreateBuilder addColumn(@NotNull String columnName, @NotNull String settings, @NotNull String comments) {
|
|
||||||
return addColumn(columnName, settings + " COMMENT " + withQuote(comments));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为该表添加一个自增列
|
|
||||||
* <p> 自增列强制要求为数字类型,非空,且为UNIQUE。
|
|
||||||
* <p> 注意:一个表只允许有一个自增列!
|
|
||||||
*
|
|
||||||
* @param columnName 列名
|
|
||||||
* @param numberType 数字类型,若省缺则为 {@link NumberType#INT}
|
|
||||||
* @param asPrimaryKey 是否为主键,若为false则设定为唯一键
|
|
||||||
* @param unsigned 是否采用 UNSIGNED (即无负数,可以增加自增键的最高数,建议为true)
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
TableCreateBuilder addAutoIncrementColumn(@NotNull String columnName, @Nullable NumberType numberType,
|
|
||||||
boolean asPrimaryKey, boolean unsigned);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为该表添加一个INT类型的自增主键列
|
|
||||||
* <p> 自增列强制要求为数字类型,非空,且为UNIQUE。
|
|
||||||
* <p> 注意:一个表只允许有一个自增列!
|
|
||||||
*
|
|
||||||
* @param columnName 列名
|
|
||||||
* @param asPrimaryKey 是否为主键,若为false则设定为唯一键
|
|
||||||
* @param unsigned 是否采用 UNSIGNED (即无负数,可以增加自增键的最高数,建议为true)
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
default TableCreateBuilder addAutoIncrementColumn(@NotNull String columnName,
|
|
||||||
boolean asPrimaryKey, boolean unsigned) {
|
|
||||||
return addAutoIncrementColumn(columnName, NumberType.INT, asPrimaryKey, unsigned);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为该表添加一个INT类型的自增列
|
|
||||||
* <p> 自增列强制要求为数字类型,非空,且为UNIQUE。
|
|
||||||
* <p> 注意:一个表只允许有一个自增列!
|
|
||||||
*
|
|
||||||
* @param columnName 列名
|
|
||||||
* @param asPrimaryKey 是否为主键,若为false则设定为唯一键
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
default TableCreateBuilder addAutoIncrementColumn(@NotNull String columnName, boolean asPrimaryKey) {
|
|
||||||
return addAutoIncrementColumn(columnName, asPrimaryKey, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为该表添加一个INT类型的自增主键列
|
|
||||||
* <p> 自增列强制要求为数字类型,非空,且为UNIQUE。
|
|
||||||
* <p> 注意:一个表只允许有一个自增列!
|
|
||||||
*
|
|
||||||
* @param columnName 列名
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
default TableCreateBuilder addAutoIncrementColumn(@NotNull String columnName) {
|
|
||||||
return addAutoIncrementColumn(columnName, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定表中的某列为索引或键。
|
|
||||||
*
|
|
||||||
* <p>创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。
|
|
||||||
* <br>虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE 和DELETE。
|
|
||||||
* <br>因此,请合理的设计索引。
|
|
||||||
*
|
|
||||||
* @param type 索引类型
|
|
||||||
* @param columnName 索引包含的列
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
default TableCreateBuilder setIndex(@NotNull String columnName,
|
|
||||||
@NotNull IndexType type) {
|
|
||||||
return setIndex(type, null, columnName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定表中的某列为索引或键。
|
|
||||||
*
|
|
||||||
* <p>创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。
|
|
||||||
* <br>虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE 和DELETE。
|
|
||||||
* <br>因此,请合理的设计索引。
|
|
||||||
*
|
|
||||||
* @param type 索引类型
|
|
||||||
* @param indexName 索引名称,缺省时将根据第一个索引列赋一个名称
|
|
||||||
* @param columnName 索引包含的列
|
|
||||||
* @param moreColumns 联合索引需要包含的列
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
TableCreateBuilder setIndex(@NotNull IndexType type, @Nullable String indexName,
|
|
||||||
@NotNull String columnName, @NotNull String... moreColumns);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 以本表位从表,为表中某列设定自参照外键(即自参照完整性)。
|
|
||||||
*
|
|
||||||
* <p>外键约束(FOREIGN KEY)是表的一个特殊字段,经常与主键约束一起使用。
|
|
||||||
* <br>外键用来建立主表与从表的关联关系,为两个表的数据建立连接,约束两个表中数据的一致性和完整性。
|
|
||||||
* <br>主表删除某条记录时,从表中与之对应的记录也必须有相应的改变。
|
|
||||||
*
|
|
||||||
* @param tableColumn 本表中的列
|
|
||||||
* @param foreignColumn 外键关联表中对应的关联列,必须为目标表的主键,即 {@link IndexType#PRIMARY_KEY}
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
default TableCreateBuilder addForeignKey(@NotNull String tableColumn, @NotNull String foreignColumn) {
|
|
||||||
return addForeignKey(tableColumn, getTableName(), foreignColumn);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 以本表位从表,为表中某列设定外键。
|
|
||||||
*
|
|
||||||
* <p>外键约束(FOREIGN KEY)是表的一个特殊字段,经常与主键约束一起使用。
|
|
||||||
* <br>外键用来建立主表与从表的关联关系,为两个表的数据建立连接,约束两个表中数据的一致性和完整性。
|
|
||||||
* <br>主表删除某条记录时,从表中与之对应的记录也必须有相应的改变。
|
|
||||||
*
|
|
||||||
* @param tableColumn 本表中的列
|
|
||||||
* @param foreignTable 外键关联主表,必须为已存在的表或本表,且必须有主键。
|
|
||||||
* @param foreignColumn 外键关联主表中对应的关联列,须满足
|
|
||||||
* <p> 1. 为主表的主键,即 {@link IndexType#PRIMARY_KEY}
|
|
||||||
* <p> 2. 数据类型必须和所要建立主键的列的数据类型相同。
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
default TableCreateBuilder addForeignKey(@NotNull String tableColumn,
|
|
||||||
@NotNull String foreignTable, @NotNull String foreignColumn) {
|
|
||||||
return addForeignKey(tableColumn, null, foreignTable, foreignColumn);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 以本表位从表,为表中某列设定外键。
|
|
||||||
*
|
|
||||||
* <p>外键约束(FOREIGN KEY)是表的一个特殊字段,经常与主键约束一起使用。
|
|
||||||
* <br>外键用来建立主表与从表的关联关系,为两个表的数据建立连接,约束两个表中数据的一致性和完整性。
|
|
||||||
* <br>主表删除某条记录时,从表中与之对应的记录也必须有相应的改变。
|
|
||||||
*
|
|
||||||
* @param tableColumn 本表中的列
|
|
||||||
* @param constraintName 约束名,缺省时将使用参数自动生成,如 <i>fk_[tableColumn]_[foreignTable]</i>
|
|
||||||
* @param foreignTable 外键关联主表,必须为已存在的表或本表,且必须有主键。
|
|
||||||
* @param foreignColumn 外键关联主表中对应的关联列,须满足
|
|
||||||
* <p> 1. 为主表的主键,即 {@link IndexType#PRIMARY_KEY}
|
|
||||||
* <p> 2. 数据类型必须和所要建立主键的列的数据类型相同。
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
default TableCreateBuilder addForeignKey(@NotNull String tableColumn, @Nullable String constraintName,
|
|
||||||
@NotNull String foreignTable, @NotNull String foreignColumn) {
|
|
||||||
return addForeignKey(tableColumn, constraintName, foreignTable, foreignColumn, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 以本表位从表,为表中某列设定外键。
|
|
||||||
*
|
|
||||||
* <p>外键约束(FOREIGN KEY)是表的一个特殊字段,经常与主键约束一起使用。
|
|
||||||
* <br>外键用来建立主表与从表的关联关系,为两个表的数据建立连接,约束两个表中数据的一致性和完整性。
|
|
||||||
* <br>主表删除某条记录时,从表中与之对应的记录也必须有相应的改变。
|
|
||||||
*
|
|
||||||
* @param tableColumn 本表中的列
|
|
||||||
* @param constraintName 约束名,缺省时将使用参数自动生成,如 <i>fk_[tableColumn]_[foreignTable]</i>
|
|
||||||
* @param foreignTable 外键关联主表,必须为已存在的表或本表,且必须有主键。
|
|
||||||
* @param foreignColumn 外键关联主表中对应的关联列,须满足
|
|
||||||
* <p> 1. 为主表的主键,即 {@link IndexType#PRIMARY_KEY}
|
|
||||||
* <p> 2. 数据类型必须和所要建立主键的列的数据类型相同。
|
|
||||||
* @param updateRule 在外键被更新时采用的规则,缺省时默认为{@link ForeignKeyRule#RESTRICT}
|
|
||||||
* @param deleteRule 在外键被删除时采用的规则,缺省时默认为{@link ForeignKeyRule#RESTRICT}
|
|
||||||
* @return {@link TableCreateBuilder}
|
|
||||||
*/
|
|
||||||
TableCreateBuilder addForeignKey(@NotNull String tableColumn, @Nullable String constraintName,
|
|
||||||
@NotNull String foreignTable, @NotNull String foreignColumn,
|
|
||||||
@Nullable ForeignKeyRule updateRule, @Nullable ForeignKeyRule deleteRule);
|
|
||||||
|
|
||||||
default String defaultTablesSettings() {
|
|
||||||
return "ENGINE=InnoDB DEFAULT CHARSET=utf8";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.builder;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLFunction;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.annotations.Unmodifiable;
|
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
public interface TableMetadataBuilder extends SQLBuilder {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return 本表是否存在
|
|
||||||
*/
|
|
||||||
CompletableFuture<Boolean> validateExist();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 对表内的数据列元数据进行读取
|
|
||||||
*
|
|
||||||
* @param columnPattern 列的名称匹配表达式, 为空则匹配所有列
|
|
||||||
* @param reader 读取的方法
|
|
||||||
* @param <R> 结果类型
|
|
||||||
* @return 读取结果
|
|
||||||
*/
|
|
||||||
<R> CompletableFuture<R> fetchColumns(@Nullable String columnPattern,
|
|
||||||
@NotNull SQLFunction<ResultSet, R> reader);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param columnPattern 需要判断的列名表达式
|
|
||||||
* @return 对应列是否存在
|
|
||||||
*/
|
|
||||||
CompletableFuture<Boolean> isColumnExists(@NotNull String columnPattern);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 列出所有表内的全部列。
|
|
||||||
*
|
|
||||||
* @return 表内全部数据列的列名
|
|
||||||
*/
|
|
||||||
default CompletableFuture<@Unmodifiable Set<String>> listColumns() {
|
|
||||||
return listColumns(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 列出所有满足表达式的列。
|
|
||||||
*
|
|
||||||
* @param columnPattern 列名表达式,为空则列出全部
|
|
||||||
* @return 所有满足表达式的列名
|
|
||||||
*/
|
|
||||||
CompletableFuture<@Unmodifiable Set<String>> listColumns(@Nullable String columnPattern);
|
|
||||||
|
|
||||||
// More coming soon.
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.builder;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.query.PreparedQueryAction;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public interface TableQueryBuilder extends ConditionalBuilder<TableQueryBuilder, PreparedQueryAction> {
|
|
||||||
|
|
||||||
@NotNull String getTableName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 选定用于查询的列名
|
|
||||||
*
|
|
||||||
* @param columnNames 列名
|
|
||||||
* @return {@link TableQueryBuilder}
|
|
||||||
*/
|
|
||||||
TableQueryBuilder selectColumns(@NotNull String... columnNames);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 对结果进行排序
|
|
||||||
*
|
|
||||||
* @param columnName 排序使用的列名
|
|
||||||
* @param asc 是否为正序排序 (为false则倒序排序)
|
|
||||||
* @return {@link TableQueryBuilder}
|
|
||||||
*/
|
|
||||||
TableQueryBuilder orderBy(@NotNull String columnName, boolean asc);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 限制查询条数,用于分页查询。
|
|
||||||
*
|
|
||||||
* @param start 开始数
|
|
||||||
* @param end 结束条数
|
|
||||||
* @return {@link TableQueryBuilder}
|
|
||||||
* @since 0.2.6
|
|
||||||
*/
|
|
||||||
TableQueryBuilder setPageLimit(int start, int end);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.builder;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
|
|
||||||
public interface UpdateBuilder extends ConditionalBuilder<UpdateBuilder, SQLAction<Integer>> {
|
|
||||||
|
|
||||||
String getTableName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加一条需要更新的字段名与值
|
|
||||||
*
|
|
||||||
* @param columnName 字段名
|
|
||||||
* @param columnValue 字段名对应的值
|
|
||||||
* @return {@link UpdateBuilder}
|
|
||||||
* @since 0.3.7
|
|
||||||
*/
|
|
||||||
UpdateBuilder addColumnValue(@NotNull String columnName, @Nullable Object columnValue);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定更新的全部字段值 <b>(此操作会覆盖之前的设定)</b>
|
|
||||||
* <p> <b>此操作会覆盖之前的设定</b>
|
|
||||||
*
|
|
||||||
* @param columnData 字段名和值的键值对
|
|
||||||
* @return {@link UpdateBuilder}
|
|
||||||
*/
|
|
||||||
UpdateBuilder setColumnValues(LinkedHashMap<@NotNull String, @Nullable Object> columnData);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定更新的全部字段值 <b>(此操作会覆盖之前的设定)</b>
|
|
||||||
* <p> <b>此操作会覆盖之前的设定</b>
|
|
||||||
*
|
|
||||||
* @param columnNames 字段名
|
|
||||||
* @param columnValues 字段名对应的值
|
|
||||||
* @return {@link UpdateBuilder}
|
|
||||||
*/
|
|
||||||
UpdateBuilder setColumnValues(@NotNull String[] columnNames, @Nullable Object[] columnValues);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设定更新的全部字段值 <b>(此操作会覆盖之前的设定)</b>
|
|
||||||
* <p> 如需同时更新多条字段,请使用 {@link #setColumnValues(String[], Object[])} 或 {@link #setColumnValues(LinkedHashMap)}
|
|
||||||
* <br>也可以使用 {@link #addColumnValue(String, Object)} 一条条的添加字段
|
|
||||||
*
|
|
||||||
* @param columnName 字段名
|
|
||||||
* @param columnValue 字段名对应的值
|
|
||||||
* @return {@link UpdateBuilder}
|
|
||||||
*/
|
|
||||||
default UpdateBuilder setColumnValues(@NotNull String columnName, @Nullable Object columnValue) {
|
|
||||||
return setColumnValues(new String[]{columnName}, new Object[]{columnValue});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.builder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 存在则更新,不存在则插入。
|
|
||||||
*
|
|
||||||
* @see ReplaceBuilder
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public interface UpsertBuilder {
|
|
||||||
|
|
||||||
String getTableName();
|
|
||||||
|
|
||||||
default UpsertBuilder setColumnNames(String[] columnNames, String updateColumn) {
|
|
||||||
throw new UnsupportedOperationException("Please use REPLACE .");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.enums;
|
|
||||||
|
|
||||||
public enum ForeignKeyRule {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 啥也不做
|
|
||||||
* <p>注意: 在Mysql中该选项实际上等同于采用默认的 {@link #RESTRICT} 设定!
|
|
||||||
*/
|
|
||||||
NO_ACTION("NO ACTION"),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 拒绝删除要求,直到使用删除键值的辅助表被手工删除,并且没有参照时(这是默认设置,也是最安全的设置)
|
|
||||||
*/
|
|
||||||
RESTRICT("RESTRICT"),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改包含与已删除键值有参照关系的所有记录,使用NULL值替换(只能用于已标记为NOT NULL的字段)
|
|
||||||
*/
|
|
||||||
SET_NULL("SET NULL"),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改包含与已删除键值有参照关系的所有记录,使用默认值替换(只能用于设定了DEFAULT的字段)
|
|
||||||
*/
|
|
||||||
SET_DEFAULT("SET DEFAULT"),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <b>级联删除</b>,删除包含与已删除键值有参照关系的所有记录
|
|
||||||
*/
|
|
||||||
CASCADE("CASCADE");
|
|
||||||
|
|
||||||
final String ruleName;
|
|
||||||
|
|
||||||
ForeignKeyRule(String ruleName) {
|
|
||||||
this.ruleName = ruleName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRuleName() {
|
|
||||||
return ruleName;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.enums;
|
|
||||||
|
|
||||||
public enum IndexType {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <b>普通索引</b>(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度。
|
|
||||||
* <br> 因此,应该只为那些最经常出现在查询条件(WHERE column=)或排序条件(ORDER BY column)中的数据列创建索引。
|
|
||||||
* <br> 只要有可能,就应该选择一个数据最整齐、最紧凑的数据列(如一个整数类型的数据列)来创建索引。
|
|
||||||
*/
|
|
||||||
INDEX("INDEX"),
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <b>唯一索引</b> 是在表上一个或者多个字段组合建立的索引,这个或者这些字段的值组合起来在表中不可以重复,用于保证数据的唯一性。
|
|
||||||
*/
|
|
||||||
UNIQUE_KEY("UNIQUE KEY"),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <b>主键索引</b> 是唯一索引的特定类型。表中创建主键时自动创建的索引 。一个表只能建立一个主索引。
|
|
||||||
*/
|
|
||||||
PRIMARY_KEY("PRIMARY KEY"),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <b>全文索引</b> 主要用来查找文本中的关键字,而不是直接与索引中的值相比较。
|
|
||||||
* <br> 请搭配 MATCH 等语句使用,而不是使用 WHERE - LIKE 。
|
|
||||||
* <br> 全文索引只可用于 CHAR、 VARCHAR 与 TEXT 系列类型。
|
|
||||||
*/
|
|
||||||
FULLTEXT_INDEX("FULLTEXT");
|
|
||||||
|
|
||||||
|
|
||||||
final String name;
|
|
||||||
|
|
||||||
IndexType(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.enums;
|
|
||||||
|
|
||||||
public enum NumberType {
|
|
||||||
|
|
||||||
TINYINT,
|
|
||||||
SMALLINT,
|
|
||||||
MEDIUMINT,
|
|
||||||
INT,
|
|
||||||
BIGINT
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.function;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface SQLBiFunction<T, U, R> {
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
R apply(@NotNull T t, @NotNull U u) throws SQLException;
|
|
||||||
|
|
||||||
default <V> SQLBiFunction<T, U, V> then(@NotNull SQLFunction<? super R, ? extends V> after) {
|
|
||||||
Objects.requireNonNull(after);
|
|
||||||
return (T t, U u) -> {
|
|
||||||
R r = apply(t, u);
|
|
||||||
if (r == null) return null;
|
|
||||||
else return after.apply(r);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,100 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.function;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLQuery;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.PreparedSQLUpdateAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.PreparedSQLUpdateBatchAction;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 异常处理器。
|
|
||||||
* <br> 在使用 {@link SQLAction#execute(SQLExceptionHandler)} 等相关方法时,
|
|
||||||
* 如果发生异常,则会调用错误处理器进行错误内容的输出提示。
|
|
||||||
*/
|
|
||||||
|
|
||||||
public interface SQLDebugHandler {
|
|
||||||
/**
|
|
||||||
* 该方法将在 {@link SQLAction#execute()} 执行前调用。
|
|
||||||
*
|
|
||||||
* @param action {@link SQLAction} 对象
|
|
||||||
* @param params 执行传入的参数列表。
|
|
||||||
* 实际上,仅有 {@link PreparedSQLUpdateAction} 和 {@link PreparedSQLUpdateBatchAction} 才会有传入参数。
|
|
||||||
*/
|
|
||||||
void beforeExecute(@NotNull SQLAction<?> action, @NotNull List<@Nullable Object[]> params);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法将在 {@link SQLQuery#close()} 执行后调用。
|
|
||||||
*
|
|
||||||
* @param query {@link SQLQuery} 对象
|
|
||||||
* @param executeNanoTime 该次查询开始执行的时间 (单位:纳秒)
|
|
||||||
* @param closeNanoTime 该次查询彻底关闭的时间 (单位:纳秒)
|
|
||||||
*/
|
|
||||||
void afterQuery(@NotNull SQLQuery query, long executeNanoTime, long closeNanoTime);
|
|
||||||
|
|
||||||
default String parseParams(@Nullable Object[] params) {
|
|
||||||
if (params == null) return "<#NULL>";
|
|
||||||
else if (params.length == 0) return "<#EMPTY>";
|
|
||||||
|
|
||||||
List<String> paramsString = new ArrayList<>();
|
|
||||||
for (Object param : params) {
|
|
||||||
if (param == null) paramsString.add("NULL");
|
|
||||||
else paramsString.add(param.toString());
|
|
||||||
}
|
|
||||||
return String.join(", ", paramsString);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("DuplicatedCode")
|
|
||||||
static SQLDebugHandler defaultHandler(Logger logger) {
|
|
||||||
return new SQLDebugHandler() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void beforeExecute(@NotNull SQLAction<?> action, @NotNull List<@Nullable Object[]> params) {
|
|
||||||
logger.info("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
||||||
logger.info("┣# ActionUUID: {}", action.getActionUUID());
|
|
||||||
logger.info("┣# ActionType: {}", action.getClass().getSimpleName());
|
|
||||||
if (action.getSQLContents().size() == 1) {
|
|
||||||
logger.info("┣# SQLContent: {}", action.getSQLContents().get(0));
|
|
||||||
} else {
|
|
||||||
logger.info("┣# SQLContents: ");
|
|
||||||
int i = 0;
|
|
||||||
for (String sqlContent : action.getSQLContents()) {
|
|
||||||
logger.info("┃ - [{}] {}", ++i, sqlContent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (params.size() == 1) {
|
|
||||||
Object[] param = params.get(0);
|
|
||||||
if (param != null) {
|
|
||||||
logger.info("┣# SQLParam: {}", parseParams(param));
|
|
||||||
}
|
|
||||||
} else if (params.size() > 1) {
|
|
||||||
logger.info("┣# SQLParams: ");
|
|
||||||
int i = 0;
|
|
||||||
for (Object[] param : params) {
|
|
||||||
logger.info("┃ - [{}] {}", ++i, parseParams(param));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logger.info("┣# CreateTime: {}", action.getCreateTime(TimeUnit.MILLISECONDS));
|
|
||||||
logger.info("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterQuery(@NotNull SQLQuery query, long executeNanoTime, long closeNanoTime) {
|
|
||||||
logger.info("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
||||||
logger.info("┣# ActionUUID: {}", query.getAction().getActionUUID());
|
|
||||||
logger.info("┣# SQLContent: {}", query.getSQLContent());
|
|
||||||
logger.info("┣# CloseTime: {} (cost {} ms)",
|
|
||||||
TimeUnit.NANOSECONDS.toMillis(closeNanoTime),
|
|
||||||
((double) (closeNanoTime - executeNanoTime) / 1000000)
|
|
||||||
);
|
|
||||||
logger.info("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.function;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 异常处理器。
|
|
||||||
* <br> 在使用 {@link SQLAction#execute(SQLExceptionHandler)} 等相关方法时,
|
|
||||||
* 如果发生异常,则会调用错误处理器进行错误内容的输出提示。
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface SQLExceptionHandler extends BiConsumer<SQLException, SQLAction<?>> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 默认的异常处理器,将详细的输出相关错误与错误来源。
|
|
||||||
*
|
|
||||||
* @param logger 用于输出错误信息的Logger。
|
|
||||||
* @return 输出详细信息的错误处理器。
|
|
||||||
*/
|
|
||||||
static SQLExceptionHandler detailed(Logger logger) {
|
|
||||||
return (exception, sqlAction) -> {
|
|
||||||
logger.error("Error occurred while executing SQL: ");
|
|
||||||
int i = 1;
|
|
||||||
for (String content : sqlAction.getSQLContents()) {
|
|
||||||
logger.error(String.format("#%d {%s}", i, content));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
exception.printStackTrace();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* “安静“ 的错误处理器,发生错误什么都不做。
|
|
||||||
* 强烈不建议把此处理器作为默认处理器使用!
|
|
||||||
*
|
|
||||||
* @return 无输出的处理器。
|
|
||||||
*/
|
|
||||||
static SQLExceptionHandler silent() {
|
|
||||||
return (exception, sqlAction) -> {
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.function;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface SQLFunction<T, R> {
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
R apply(@NotNull T t) throws SQLException;
|
|
||||||
|
|
||||||
default <V> SQLFunction<V, R> compose(@NotNull SQLFunction<? super V, ? extends T> before) {
|
|
||||||
Objects.requireNonNull(before);
|
|
||||||
return (V v) -> {
|
|
||||||
T t = before.apply(v);
|
|
||||||
if (t == null) return null;
|
|
||||||
else return apply(t);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
default <V> SQLFunction<T, V> then(@NotNull SQLFunction<? super R, ? extends V> after) {
|
|
||||||
Objects.requireNonNull(after);
|
|
||||||
return (T t) -> {
|
|
||||||
R r = apply(t);
|
|
||||||
if (r == null) return null;
|
|
||||||
else return after.apply(r);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.function;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Contract;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface SQLHandler<T> {
|
|
||||||
|
|
||||||
void accept(@NotNull T t) throws SQLException;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Contract(pure = true)
|
|
||||||
default SQLHandler<T> andThen(@NotNull SQLHandler<? super T> after) {
|
|
||||||
Objects.requireNonNull(after);
|
|
||||||
return (T t) -> {
|
|
||||||
accept(t);
|
|
||||||
after.accept(t);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.table;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLManager;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLTable;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class NamedSQLTable implements SQLTable {
|
|
||||||
|
|
||||||
private final @NotNull String tableName;
|
|
||||||
|
|
||||||
protected @Nullable String tablePrefix;
|
|
||||||
protected @Nullable SQLManager manager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 请调用 {@link NamedSQLTable} 下的静态方法进行对象的初始化。
|
|
||||||
*
|
|
||||||
* @param tableName 该表的名称
|
|
||||||
*/
|
|
||||||
public NamedSQLTable(@NotNull String tableName) {
|
|
||||||
this.tableName = tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull String getTableName() {
|
|
||||||
return (tablePrefix != null ? tablePrefix : "") + tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable SQLManager getSQLManager() {
|
|
||||||
return this.manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用指定 SQLManager 进行本示例的初始化。
|
|
||||||
*
|
|
||||||
* @param sqlManager {@link SQLManager}
|
|
||||||
* @param tablePrefix 表名前缀
|
|
||||||
* @return 本表是否为首次创建
|
|
||||||
* @throws SQLException 出现任何错误时抛出
|
|
||||||
*/
|
|
||||||
public abstract boolean create(@NotNull SQLManager sqlManager, @Nullable String tablePrefix) throws SQLException;
|
|
||||||
|
|
||||||
public boolean create(@NotNull SQLManager sqlManager) throws SQLException {
|
|
||||||
return create(sqlManager, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,108 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.util;
|
|
||||||
|
|
||||||
import java.text.DateFormat;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
public class TimeDateUtils {
|
|
||||||
public static final DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
||||||
|
|
||||||
public TimeDateUtils() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到当前时间文本。
|
|
||||||
*
|
|
||||||
* @return 时间文本 格式{@link TimeDateUtils#getFormat()}
|
|
||||||
*/
|
|
||||||
public static String getCurrentTime() {
|
|
||||||
return getTimeString(System.currentTimeMillis());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到一个时间戳的文本
|
|
||||||
*
|
|
||||||
* @param timeMillis 时间戳
|
|
||||||
* @return 时间文本 格式{@link TimeDateUtils#getFormat()}
|
|
||||||
*/
|
|
||||||
public static String getTimeString(long timeMillis) {
|
|
||||||
return getFormat().format(new Date(timeMillis));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到一个日期时间的文本
|
|
||||||
*
|
|
||||||
* @param time 日期时间
|
|
||||||
* @return 时间文本 格式{@link TimeDateUtils#getFormat()}
|
|
||||||
*/
|
|
||||||
public static String getTimeString(Date time) {
|
|
||||||
return getFormat().format(time);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到一个时间文本的时间戳
|
|
||||||
*
|
|
||||||
* @param timeString 时间文本
|
|
||||||
* @return 时间戳 格式{@link TimeDateUtils#getFormat()}
|
|
||||||
*/
|
|
||||||
public static long parseTimeMillis(String timeString) {
|
|
||||||
if (timeString == null) {
|
|
||||||
return -1L;
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
return format.parse(timeString).getTime();
|
|
||||||
} catch (ParseException var2) {
|
|
||||||
return -1L;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 得到一个时间文本的对应日期实例
|
|
||||||
*
|
|
||||||
* @param timeString 时间文本
|
|
||||||
* @return 日期实例 格式{@link TimeDateUtils#getFormat()}
|
|
||||||
*/
|
|
||||||
public static Date getTimeDate(String timeString) {
|
|
||||||
if (timeString == null) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
return format.parse(timeString);
|
|
||||||
} catch (ParseException var2) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将秒数转化为 DD:hh:mm:ss 格式
|
|
||||||
*
|
|
||||||
* @param allSeconds 秒数
|
|
||||||
* @return DD:hh:mm:ss格式文本
|
|
||||||
*/
|
|
||||||
public static String toDHMSStyle(long allSeconds) {
|
|
||||||
long days = allSeconds / 86400L;
|
|
||||||
long hours = allSeconds % 86400L / 3600L;
|
|
||||||
long minutes = allSeconds % 3600L / 60L;
|
|
||||||
long seconds = allSeconds % 60L;
|
|
||||||
String DateTimes;
|
|
||||||
if (days > 0L) {
|
|
||||||
DateTimes = days + "天" + (hours > 0L ? hours + "小时" : "") + (minutes > 0L ? minutes + "分钟" : "") + (seconds > 0L ? seconds + "秒" : "");
|
|
||||||
} else if (hours > 0L) {
|
|
||||||
DateTimes = hours + "小时" + (minutes > 0L ? minutes + "分钟" : "") + (seconds > 0L ? seconds + "秒" : "");
|
|
||||||
} else if (minutes > 0L) {
|
|
||||||
DateTimes = minutes + "分钟" + (seconds > 0L ? seconds + "秒" : "");
|
|
||||||
} else {
|
|
||||||
DateTimes = seconds + "秒";
|
|
||||||
}
|
|
||||||
|
|
||||||
return DateTimes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DateFormat getFormat() {
|
|
||||||
return format;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.api.util;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class UUIDUtil {
|
|
||||||
|
|
||||||
private static final Pattern COMPILE = Pattern.compile("-", Pattern.LITERAL);
|
|
||||||
|
|
||||||
public static UUID random() {
|
|
||||||
return UUID.randomUUID();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toString(UUID uuid, boolean withDash) {
|
|
||||||
if (withDash) return uuid.toString();
|
|
||||||
else return COMPILE.matcher(uuid.toString()).replaceAll(Matcher.quoteReplacement(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UUID toUUID(String s) {
|
|
||||||
if (s.length() == 36) {
|
|
||||||
return UUID.fromString(s);
|
|
||||||
} else {
|
|
||||||
return UUID.fromString(s.substring(0, 8) + '-' + s.substring(8, 12) + '-' + s.substring(12, 16) + '-' + s.substring(16, 20) + '-' + s.substring(20));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.builder;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public abstract class AbstractSQLBuilder implements SQLBuilder {
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
final SQLManagerImpl sqlManager;
|
|
||||||
|
|
||||||
public AbstractSQLBuilder(@NotNull SQLManagerImpl manager) {
|
|
||||||
Objects.requireNonNull(manager, "SQLManager must not be null");
|
|
||||||
this.sqlManager = manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull SQLManagerImpl getManager() {
|
|
||||||
return this.sqlManager;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,159 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.builder.impl;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.builder.ConditionalBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.builder.AbstractSQLBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.sql.Time;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import static com.io.yutian.elementoriginlib.sql.api.SQLBuilder.withBackQuote;
|
|
||||||
|
|
||||||
public abstract class AbstractConditionalBuilder<B extends ConditionalBuilder<B, T>, T extends SQLAction<?>>
|
|
||||||
extends AbstractSQLBuilder implements ConditionalBuilder<B, T> {
|
|
||||||
|
|
||||||
ArrayList<String> conditionSQLs = new ArrayList<>();
|
|
||||||
ArrayList<Object> conditionParams = new ArrayList<>();
|
|
||||||
int limit = -1;
|
|
||||||
|
|
||||||
public AbstractConditionalBuilder(@NotNull SQLManagerImpl manager) {
|
|
||||||
super(manager);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract B getThis();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public B setConditions(@Nullable String condition) {
|
|
||||||
this.conditionSQLs = new ArrayList<>();
|
|
||||||
this.conditionParams = new ArrayList<>();
|
|
||||||
if (condition != null) this.conditionSQLs.add(condition);
|
|
||||||
return getThis();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public B setConditions(
|
|
||||||
LinkedHashMap<@NotNull String, @Nullable Object> conditions
|
|
||||||
) {
|
|
||||||
conditions.forEach(this::addCondition);
|
|
||||||
return getThis();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public B addCondition(@Nullable String condition) {
|
|
||||||
this.conditionSQLs.add(condition);
|
|
||||||
return getThis();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public B addCondition(@NotNull String columnName, @Nullable Object queryValue) {
|
|
||||||
Objects.requireNonNull(columnName, "columnName could not be null");
|
|
||||||
if (queryValue == null) {
|
|
||||||
return addCondition(withBackQuote(columnName) + " IS NULL");
|
|
||||||
} else {
|
|
||||||
return addCondition(columnName, "=", queryValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public B addCondition(
|
|
||||||
@NotNull String columnName, @NotNull String operator, @Nullable Object queryValue
|
|
||||||
) {
|
|
||||||
Objects.requireNonNull(columnName, "columnName could not be null");
|
|
||||||
Objects.requireNonNull(operator, "operator could not be null (e.g. > or = or <) ");
|
|
||||||
addCondition(withBackQuote(columnName) + " " + operator + " ?");
|
|
||||||
this.conditionParams.add(queryValue);
|
|
||||||
return getThis();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public B addCondition(
|
|
||||||
@NotNull String[] columnNames, @Nullable Object[] queryValues
|
|
||||||
) {
|
|
||||||
Objects.requireNonNull(columnNames, "columnName could not be null");
|
|
||||||
if (queryValues == null || columnNames.length != queryValues.length) {
|
|
||||||
throw new RuntimeException("queryNames are not match with queryValues");
|
|
||||||
}
|
|
||||||
for (int i = 0; i < columnNames.length; i++) {
|
|
||||||
addCondition(columnNames[i], queryValues[i]);
|
|
||||||
}
|
|
||||||
return getThis();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public B addNotNullCondition(@NotNull String columnName) {
|
|
||||||
Objects.requireNonNull(columnName, "columnName could not be null");
|
|
||||||
return addCondition(withBackQuote(columnName) + " IS NOT NULL");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public B addTimeCondition(
|
|
||||||
@NotNull String columnName, @Nullable Date startDate, @Nullable Date endDate
|
|
||||||
) {
|
|
||||||
Objects.requireNonNull(columnName, "columnName could not be null");
|
|
||||||
if (startDate == null && endDate == null) return getThis(); // 都不限定时间,不用判断了
|
|
||||||
if (startDate != null) {
|
|
||||||
addCondition(withBackQuote(columnName) + " BETWEEN ? AND ?");
|
|
||||||
this.conditionParams.add(startDate);
|
|
||||||
if (endDate != null) {
|
|
||||||
this.conditionParams.add(endDate);
|
|
||||||
} else {
|
|
||||||
if (startDate instanceof java.sql.Date) {
|
|
||||||
this.conditionParams.add(new java.sql.Date(System.currentTimeMillis()));
|
|
||||||
} else if (startDate instanceof Time) {
|
|
||||||
this.conditionParams.add(new Time(System.currentTimeMillis()));
|
|
||||||
} else {
|
|
||||||
this.conditionParams.add(new Timestamp(System.currentTimeMillis()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
addCondition(columnName, "<=", endDate);
|
|
||||||
}
|
|
||||||
return getThis();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public B setLimit(int limit) {
|
|
||||||
this.limit = limit;
|
|
||||||
return getThis();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String buildConditionSQL() {
|
|
||||||
|
|
||||||
if (!conditionSQLs.isEmpty()) {
|
|
||||||
StringBuilder conditionBuilder = new StringBuilder();
|
|
||||||
conditionBuilder.append("WHERE").append(" ");
|
|
||||||
Iterator<String> iterator = conditionSQLs.iterator();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
conditionBuilder.append(iterator.next());
|
|
||||||
if (iterator.hasNext()) conditionBuilder.append(" AND ");
|
|
||||||
}
|
|
||||||
return conditionBuilder.toString().trim();
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String buildLimitSQL() {
|
|
||||||
return limit > 0 ? "LIMIT " + limit : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ArrayList<Object> getConditionParams() {
|
|
||||||
return conditionParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean hasConditions() {
|
|
||||||
return this.conditionSQLs != null && !this.conditionSQLs.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean hasConditionParams() {
|
|
||||||
return hasConditions() && getConditionParams() != null && !getConditionParams().isEmpty();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.builder.impl;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.action.PreparedSQLUpdateActionImpl;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.PreparedSQLUpdateAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.builder.DeleteBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import static com.io.yutian.elementoriginlib.sql.api.SQLBuilder.withBackQuote;
|
|
||||||
|
|
||||||
public class DeleteBuilderImpl
|
|
||||||
extends AbstractConditionalBuilder<DeleteBuilder, SQLAction<Integer>>
|
|
||||||
implements DeleteBuilder {
|
|
||||||
|
|
||||||
protected final String tableName;
|
|
||||||
|
|
||||||
public DeleteBuilderImpl(@NotNull SQLManagerImpl manager, @NotNull String tableName) {
|
|
||||||
super(manager);
|
|
||||||
Objects.requireNonNull(tableName);
|
|
||||||
this.tableName = tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PreparedSQLUpdateAction<Integer> build() {
|
|
||||||
|
|
||||||
StringBuilder sqlBuilder = new StringBuilder();
|
|
||||||
|
|
||||||
sqlBuilder.append("DELETE FROM ").append(withBackQuote(getTableName()));
|
|
||||||
|
|
||||||
if (hasConditions()) sqlBuilder.append(" ").append(buildConditionSQL());
|
|
||||||
if (limit > 0) sqlBuilder.append(" ").append(buildLimitSQL());
|
|
||||||
|
|
||||||
return new PreparedSQLUpdateActionImpl<>(
|
|
||||||
getManager(), Integer.class, sqlBuilder.toString(),
|
|
||||||
(hasConditionParams() ? getConditionParams() : null)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTableName() {
|
|
||||||
return tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected DeleteBuilderImpl getThis() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.builder.impl;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.builder.InsertBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.builder.AbstractSQLBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import static com.io.yutian.elementoriginlib.sql.api.SQLBuilder.withBackQuote;
|
|
||||||
|
|
||||||
public abstract class InsertBuilderImpl<T extends SQLAction<?>>
|
|
||||||
extends AbstractSQLBuilder implements InsertBuilder<T> {
|
|
||||||
|
|
||||||
protected final String tableName;
|
|
||||||
protected boolean ignore;
|
|
||||||
|
|
||||||
public InsertBuilderImpl(@NotNull SQLManagerImpl manager, String tableName) {
|
|
||||||
super(manager);
|
|
||||||
Objects.requireNonNull(tableName);
|
|
||||||
this.tableName = tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isIgnore() {
|
|
||||||
return ignore;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InsertBuilder<T> setIgnore(boolean ignore) {
|
|
||||||
this.ignore = ignore;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static String buildSQL(String tableName, boolean ignore, List<String> columnNames) {
|
|
||||||
return buildSQL("INSERT "+(ignore ? "IGNORE " : "")+"INTO", tableName, columnNames);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static String buildSQL(String sqlPrefix, String tableName, List<String> columnNames) {
|
|
||||||
int valueLength = columnNames.size();
|
|
||||||
StringBuilder sqlBuilder = new StringBuilder();
|
|
||||||
|
|
||||||
sqlBuilder.append(sqlPrefix).append(" ").append(withBackQuote(tableName)).append("(");
|
|
||||||
Iterator<String> iterator = columnNames.iterator();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
sqlBuilder.append(withBackQuote(iterator.next()));
|
|
||||||
if (iterator.hasNext()) sqlBuilder.append(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlBuilder.append(") VALUES (");
|
|
||||||
|
|
||||||
for (int i = 0; i < valueLength; i++) {
|
|
||||||
sqlBuilder.append("?");
|
|
||||||
if (i != valueLength - 1) {
|
|
||||||
sqlBuilder.append(", ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sqlBuilder.append(")");
|
|
||||||
return sqlBuilder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTableName() {
|
|
||||||
return tableName;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.builder.impl;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.action.query.PreparedQueryActionImpl;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.action.query.QueryActionImpl;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.query.PreparedQueryAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.query.QueryAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.builder.QueryBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.builder.TableQueryBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.builder.AbstractSQLBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class QueryBuilderImpl extends AbstractSQLBuilder implements QueryBuilder {
|
|
||||||
public QueryBuilderImpl(@NotNull SQLManagerImpl manager) {
|
|
||||||
super(manager);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public QueryAction withSQL(@NotNull String sql) {
|
|
||||||
Objects.requireNonNull(sql, "sql could not be null");
|
|
||||||
return new QueryActionImpl(getManager(), sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PreparedQueryAction withPreparedSQL(@NotNull String sql) {
|
|
||||||
Objects.requireNonNull(sql, "sql could not be null");
|
|
||||||
return new PreparedQueryActionImpl(getManager(), sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableQueryBuilder inTable(@NotNull String tableName) {
|
|
||||||
Objects.requireNonNull(tableName, "tableName could not be null");
|
|
||||||
return new TableQueryBuilderImpl(getManager(), tableName);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.builder.impl;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.builder.ReplaceBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.builder.AbstractSQLBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public abstract class ReplaceBuilderImpl<T extends SQLAction<?>>
|
|
||||||
extends AbstractSQLBuilder implements ReplaceBuilder<T> {
|
|
||||||
|
|
||||||
protected final @NotNull String tableName;
|
|
||||||
|
|
||||||
public ReplaceBuilderImpl(@NotNull SQLManagerImpl manager, @NotNull String tableName) {
|
|
||||||
super(manager);
|
|
||||||
this.tableName = tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static String buildSQL(String tableName, List<String> columnNames) {
|
|
||||||
return InsertBuilderImpl.buildSQL("REPLACE INTO", tableName, columnNames);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getTableName() {
|
|
||||||
return tableName;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,147 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.builder.impl;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.action.SQLUpdateActionImpl;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.builder.TableAlterBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.enums.IndexType;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.builder.AbstractSQLBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import static com.io.yutian.elementoriginlib.sql.api.SQLBuilder.withBackQuote;
|
|
||||||
import static com.io.yutian.elementoriginlib.sql.api.SQLBuilder.withQuote;
|
|
||||||
|
|
||||||
public class TableAlterBuilderImpl extends AbstractSQLBuilder implements TableAlterBuilder {
|
|
||||||
|
|
||||||
protected final @NotNull String tableName;
|
|
||||||
|
|
||||||
public TableAlterBuilderImpl(@NotNull SQLManagerImpl manager, @NotNull String tableName) {
|
|
||||||
super(manager);
|
|
||||||
this.tableName = tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull String getTableName() {
|
|
||||||
return tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLAction<Integer> renameTo(@NotNull String newTableName) {
|
|
||||||
Objects.requireNonNull(newTableName, "table name could not be null");
|
|
||||||
return createAction("ALTER TABLE " + withBackQuote(tableName) + " RENAME TO " + withBackQuote(newTableName));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLAction<Integer> changeComment(@NotNull String newTableComment) {
|
|
||||||
Objects.requireNonNull(newTableComment, "table comment could not be null");
|
|
||||||
return createAction("ALTER TABLE " + withBackQuote(getTableName()) + " COMMENT " + withQuote(newTableComment));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLAction<Integer> setAutoIncrementIndex(int index) {
|
|
||||||
return createAction("ALTER TABLE " + withBackQuote(getTableName()) + " AUTO_INCREMENT=" + index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLAction<Integer> addIndex(@NotNull IndexType indexType, @Nullable String indexName,
|
|
||||||
@NotNull String columnName, @NotNull String... moreColumns) {
|
|
||||||
Objects.requireNonNull(indexType, "indexType could not be null");
|
|
||||||
Objects.requireNonNull(columnName, "column names could not be null");
|
|
||||||
Objects.requireNonNull(moreColumns, "column names could not be null");
|
|
||||||
return createAction(
|
|
||||||
"ALTER TABLE " + withBackQuote(getTableName()) + " ADD "
|
|
||||||
+ TableCreateBuilderImpl.buildIndexSettings(indexType, indexName, columnName, moreColumns)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLAction<Integer> dropIndex(@NotNull String indexName) {
|
|
||||||
Objects.requireNonNull(indexName, "indexName could not be null");
|
|
||||||
return createAction(
|
|
||||||
"ALTER TABLE " + withBackQuote(getTableName()) + " DROP INDEX " + withBackQuote(indexName)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLAction<Integer> dropForeignKey(@NotNull String keySymbol) {
|
|
||||||
Objects.requireNonNull(keySymbol, "keySymbol could not be null");
|
|
||||||
return createAction(
|
|
||||||
"ALTER TABLE " + withBackQuote(getTableName()) + " DROP FOREIGN KEY " + withBackQuote(keySymbol)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLAction<Integer> dropPrimaryKey() {
|
|
||||||
return createAction(
|
|
||||||
"ALTER TABLE " + withBackQuote(getTableName()) + " DROP PRIMARY KEY"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLAction<Integer> addColumn(@NotNull String columnName, @NotNull String settings, @Nullable String afterColumn) {
|
|
||||||
Objects.requireNonNull(columnName, "columnName could not be null");
|
|
||||||
Objects.requireNonNull(settings, "settings could not be null");
|
|
||||||
String orderSettings = null;
|
|
||||||
if (afterColumn != null) {
|
|
||||||
if (afterColumn.length() > 0) {
|
|
||||||
orderSettings = "AFTER " + withBackQuote(afterColumn);
|
|
||||||
} else {
|
|
||||||
orderSettings = "FIRST";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return createAction(
|
|
||||||
"ALTER TABLE " + withBackQuote(getTableName()) + " ADD " + withBackQuote(columnName) + " " + settings
|
|
||||||
+ (orderSettings != null ? " " + orderSettings : "")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLAction<Integer> renameColumn(@NotNull String columnName, @NotNull String newName) {
|
|
||||||
Objects.requireNonNull(columnName, "columnName could not be null");
|
|
||||||
Objects.requireNonNull(newName, "please specify new column name");
|
|
||||||
return createAction(
|
|
||||||
"ALTER TABLE " + withBackQuote(getTableName()) + " RENAME COLUMN " + withBackQuote(columnName) + " TO " + withBackQuote(newName)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLAction<Integer> modifyColumn(@NotNull String columnName, @NotNull String settings) {
|
|
||||||
Objects.requireNonNull(columnName, "columnName could not be null");
|
|
||||||
Objects.requireNonNull(settings, "please specify new column settings");
|
|
||||||
return createAction(
|
|
||||||
"ALTER TABLE " + withBackQuote(getTableName()) + " MODIFY COLUMN " + withBackQuote(columnName) + " " + settings
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLAction<Integer> removeColumn(@NotNull String columnName) {
|
|
||||||
Objects.requireNonNull(columnName, "columnName could not be null");
|
|
||||||
return createAction(
|
|
||||||
"ALTER TABLE " + withBackQuote(getTableName()) + " DROP " + withBackQuote(columnName)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLAction<Integer> setColumnDefault(@NotNull String columnName, @NotNull String defaultValue) {
|
|
||||||
Objects.requireNonNull(columnName, "columnName could not be null");
|
|
||||||
Objects.requireNonNull(defaultValue, "defaultValue could not be null, if you need to remove the default value, please use #removeColumnDefault().");
|
|
||||||
return createAction(
|
|
||||||
"ALTER TABLE " + withBackQuote(getTableName()) + " ALTER " + withBackQuote(columnName) + " SET DEFAULT " + defaultValue
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLAction<Integer> removeColumnDefault(@NotNull String columnName) {
|
|
||||||
Objects.requireNonNull(columnName, "columnName could not be null");
|
|
||||||
return createAction(
|
|
||||||
"ALTER TABLE " + withBackQuote(getTableName()) + " ALTER " + withBackQuote(columnName) + " DROP DEFAULT"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private SQLUpdateActionImpl<Integer> createAction(@NotNull String sql) {
|
|
||||||
return new SQLUpdateActionImpl<>(getManager(), Integer.class, sql);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,172 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.builder.impl;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.action.SQLUpdateActionImpl;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.SQLUpdateAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.builder.TableCreateBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.enums.ForeignKeyRule;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.enums.IndexType;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.enums.NumberType;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.builder.AbstractSQLBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import static com.io.yutian.elementoriginlib.sql.api.SQLBuilder.withBackQuote;
|
|
||||||
import static com.io.yutian.elementoriginlib.sql.api.SQLBuilder.withQuote;
|
|
||||||
|
|
||||||
public class TableCreateBuilderImpl extends AbstractSQLBuilder implements TableCreateBuilder {
|
|
||||||
|
|
||||||
protected final @NotNull String tableName;
|
|
||||||
@NotNull
|
|
||||||
final List<String> indexes = new ArrayList<>();
|
|
||||||
@NotNull
|
|
||||||
final List<String> foreignKeys = new ArrayList<>();
|
|
||||||
@NotNull List<String> columns = new ArrayList<>();
|
|
||||||
@NotNull String tableSettings = defaultTablesSettings();
|
|
||||||
@Nullable String tableComment;
|
|
||||||
|
|
||||||
public TableCreateBuilderImpl(SQLManagerImpl manager, @NotNull String tableName) {
|
|
||||||
super(manager);
|
|
||||||
this.tableName = tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static String buildIndexSettings(@NotNull IndexType indexType, @Nullable String indexName,
|
|
||||||
@NotNull String columnName, @NotNull String... moreColumns) {
|
|
||||||
Objects.requireNonNull(indexType, "indexType could not be null");
|
|
||||||
Objects.requireNonNull(columnName, "column names could not be null");
|
|
||||||
Objects.requireNonNull(moreColumns, "column names could not be null");
|
|
||||||
StringBuilder indexBuilder = new StringBuilder();
|
|
||||||
|
|
||||||
indexBuilder.append(indexType.getName()).append(" ");
|
|
||||||
if (indexName != null) {
|
|
||||||
indexBuilder.append(withBackQuote(indexName));
|
|
||||||
}
|
|
||||||
indexBuilder.append("(");
|
|
||||||
indexBuilder.append(withBackQuote(columnName));
|
|
||||||
|
|
||||||
if (moreColumns.length > 0) {
|
|
||||||
indexBuilder.append(", ");
|
|
||||||
|
|
||||||
for (int i = 0; i < moreColumns.length; i++) {
|
|
||||||
indexBuilder.append(withBackQuote(moreColumns[i]));
|
|
||||||
if (i != moreColumns.length - 1) indexBuilder.append(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
indexBuilder.append(")");
|
|
||||||
|
|
||||||
return indexBuilder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getTableName() {
|
|
||||||
return this.tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getTableSettings() {
|
|
||||||
return this.tableSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLUpdateAction<Integer> build() {
|
|
||||||
StringBuilder createSQL = new StringBuilder();
|
|
||||||
createSQL.append("CREATE TABLE IF NOT EXISTS ").append(withBackQuote(tableName));
|
|
||||||
createSQL.append("(");
|
|
||||||
createSQL.append(String.join(", ", columns));
|
|
||||||
if (indexes.size() > 0) {
|
|
||||||
createSQL.append(", ");
|
|
||||||
createSQL.append(String.join(", ", indexes));
|
|
||||||
}
|
|
||||||
if (foreignKeys.size() > 0) {
|
|
||||||
createSQL.append(", ");
|
|
||||||
createSQL.append(String.join(", ", foreignKeys));
|
|
||||||
}
|
|
||||||
createSQL.append(") ").append(getTableSettings());
|
|
||||||
|
|
||||||
if (tableComment != null) {
|
|
||||||
createSQL.append(" COMMENT ").append(withQuote(tableComment));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SQLUpdateActionImpl<>(getManager(), Integer.class, createSQL.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableCreateBuilder addColumn(@NotNull String column) {
|
|
||||||
Objects.requireNonNull(column, "column could not be null");
|
|
||||||
this.columns.add(column);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableCreateBuilder addAutoIncrementColumn(@NotNull String columnName, @Nullable NumberType numberType,
|
|
||||||
boolean asPrimaryKey, boolean unsigned) {
|
|
||||||
return addColumn(columnName,
|
|
||||||
(numberType == null ? NumberType.INT : numberType).name()
|
|
||||||
+ (unsigned ? " UNSIGNED " : " ")
|
|
||||||
+ "NOT NULL AUTO_INCREMENT " + (asPrimaryKey ? "PRIMARY KEY" : "UNIQUE KEY")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableCreateBuilder setIndex(@NotNull IndexType type, @Nullable String indexName,
|
|
||||||
@NotNull String columnName, @NotNull String... moreColumns) {
|
|
||||||
Objects.requireNonNull(columnName, "columnName could not be null");
|
|
||||||
this.indexes.add(buildIndexSettings(type, indexName, columnName, moreColumns));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableCreateBuilder addForeignKey(@NotNull String tableColumn, @Nullable String constraintName,
|
|
||||||
@NotNull String foreignTable, @NotNull String foreignColumn,
|
|
||||||
@Nullable ForeignKeyRule updateRule, @Nullable ForeignKeyRule deleteRule) {
|
|
||||||
Objects.requireNonNull(tableColumn, "tableColumn could not be null");
|
|
||||||
Objects.requireNonNull(foreignTable, "foreignTable could not be null");
|
|
||||||
Objects.requireNonNull(foreignColumn, "foreignColumn could not be null");
|
|
||||||
|
|
||||||
StringBuilder keyBuilder = new StringBuilder();
|
|
||||||
|
|
||||||
keyBuilder.append("CONSTRAINT ");
|
|
||||||
if (constraintName == null) {
|
|
||||||
keyBuilder.append(withBackQuote("fk_" + tableColumn + "_" + foreignTable));
|
|
||||||
} else {
|
|
||||||
keyBuilder.append(withBackQuote(constraintName));
|
|
||||||
}
|
|
||||||
keyBuilder.append(" ");
|
|
||||||
keyBuilder.append("FOREIGN KEY (").append(withBackQuote(tableColumn)).append(") ");
|
|
||||||
keyBuilder.append("REFERENCES ").append(withBackQuote(foreignTable)).append("(").append(withBackQuote(foreignColumn)).append(")");
|
|
||||||
|
|
||||||
if (updateRule != null) keyBuilder.append(" ON UPDATE ").append(updateRule.getRuleName());
|
|
||||||
if (deleteRule != null) keyBuilder.append(" ON DELETE ").append(deleteRule.getRuleName());
|
|
||||||
|
|
||||||
this.foreignKeys.add(keyBuilder.toString());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableCreateBuilder setColumns(@NotNull String... columns) {
|
|
||||||
Objects.requireNonNull(columns, "columns could not be null");
|
|
||||||
this.columns = Arrays.asList(columns);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableCreateBuilder setTableSettings(@NotNull String settings) {
|
|
||||||
Objects.requireNonNull(settings, "settings could not be null");
|
|
||||||
this.tableSettings = settings;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableCreateBuilder setTableComment(@Nullable String comment) {
|
|
||||||
this.tableComment = comment;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.builder.impl;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.builder.TableMetadataBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLBiFunction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLFunction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.builder.AbstractSQLBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DatabaseMetaData;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
public class TableMetadataBuilderImpl
|
|
||||||
extends AbstractSQLBuilder
|
|
||||||
implements TableMetadataBuilder {
|
|
||||||
|
|
||||||
protected final @NotNull String tablePattern;
|
|
||||||
|
|
||||||
public TableMetadataBuilderImpl(@NotNull SQLManagerImpl manager, @NotNull String tablePattern) {
|
|
||||||
super(manager);
|
|
||||||
this.tablePattern = tablePattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletableFuture<Boolean> validateExist() {
|
|
||||||
return validate((meta, conn) -> meta.getTables(conn.getCatalog(), conn.getSchema(), tablePattern.toUpperCase(), new String[]{"TABLE"}));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <R> CompletableFuture<R> fetchColumns(@Nullable String columnPattern,
|
|
||||||
@NotNull SQLFunction<ResultSet, R> reader) {
|
|
||||||
return getManager().fetchMetadata((meta, conn) -> meta.getColumns(
|
|
||||||
conn.getCatalog(), conn.getSchema(), tablePattern.toUpperCase(),
|
|
||||||
Optional.ofNullable(columnPattern).map(String::toUpperCase).orElse("%")
|
|
||||||
), reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletableFuture<Boolean> isColumnExists(@NotNull String columnPattern) {
|
|
||||||
return validate((meta, conn) -> meta.getColumns(
|
|
||||||
conn.getCatalog(), conn.getSchema(),
|
|
||||||
tablePattern.toUpperCase(), columnPattern.toUpperCase()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompletableFuture<Set<String>> listColumns(@Nullable String columnPattern) {
|
|
||||||
return fetchColumns(columnPattern, (rs) -> {
|
|
||||||
Set<String> data = new LinkedHashSet<>();
|
|
||||||
while (rs.next()) {
|
|
||||||
data.add(rs.getString("COLUMN_NAME"));
|
|
||||||
}
|
|
||||||
return Collections.unmodifiableSet(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fast validate EXISTS.
|
|
||||||
*
|
|
||||||
* @param supplier supplier to get result set
|
|
||||||
* @return result future
|
|
||||||
*/
|
|
||||||
private CompletableFuture<Boolean> validate(SQLBiFunction<DatabaseMetaData, Connection, ResultSet> supplier) {
|
|
||||||
return getManager().fetchMetadata(supplier, ResultSet::next);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,94 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.builder.impl;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.action.query.PreparedQueryActionImpl;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.query.PreparedQueryAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.builder.TableQueryBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import static com.io.yutian.elementoriginlib.sql.api.SQLBuilder.withBackQuote;
|
|
||||||
|
|
||||||
public class TableQueryBuilderImpl
|
|
||||||
extends AbstractConditionalBuilder<TableQueryBuilder, PreparedQueryAction>
|
|
||||||
implements TableQueryBuilder {
|
|
||||||
|
|
||||||
|
|
||||||
protected final @NotNull String tableName;
|
|
||||||
|
|
||||||
String[] columns;
|
|
||||||
|
|
||||||
@Nullable String orderBy;
|
|
||||||
|
|
||||||
int[] pageLimit;
|
|
||||||
|
|
||||||
public TableQueryBuilderImpl(@NotNull SQLManagerImpl manager, @NotNull String tableName) {
|
|
||||||
super(manager);
|
|
||||||
this.tableName = tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PreparedQueryActionImpl build() {
|
|
||||||
StringBuilder sqlBuilder = new StringBuilder();
|
|
||||||
sqlBuilder.append("SELECT").append(" ");
|
|
||||||
if (columns == null || columns.length < 1) {
|
|
||||||
sqlBuilder.append("*");
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < columns.length; i++) {
|
|
||||||
String name = columns[i];
|
|
||||||
sqlBuilder.append(withBackQuote(name));
|
|
||||||
if (i != columns.length - 1) {
|
|
||||||
sqlBuilder.append(",");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlBuilder.append(" ").append("FROM").append(" ").append(withBackQuote(tableName));
|
|
||||||
|
|
||||||
if (hasConditions()) sqlBuilder.append(" ").append(buildConditionSQL());
|
|
||||||
|
|
||||||
if (orderBy != null) sqlBuilder.append(" ").append(orderBy);
|
|
||||||
|
|
||||||
if (pageLimit != null && pageLimit.length == 2) {
|
|
||||||
sqlBuilder.append(" LIMIT ").append(pageLimit[0]).append(",").append(pageLimit[1]);
|
|
||||||
} else if (limit > 0) {
|
|
||||||
sqlBuilder.append(" ").append(buildLimitSQL());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return new PreparedQueryActionImpl(getManager(), sqlBuilder.toString())
|
|
||||||
.setParams(hasConditionParams() ? getConditionParams() : null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getTableName() {
|
|
||||||
return tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableQueryBuilderImpl selectColumns(@NotNull String... columnNames) {
|
|
||||||
Objects.requireNonNull(columnNames, "columnNames could not be null");
|
|
||||||
this.columns = columnNames;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableQueryBuilder orderBy(@NotNull String columnName, boolean asc) {
|
|
||||||
Objects.requireNonNull(columnName, "columnName could not be null");
|
|
||||||
this.orderBy = "ORDER BY " + withBackQuote(columnName) + " " + (asc ? "ASC" : "DESC");
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableQueryBuilder setPageLimit(int start, int end) {
|
|
||||||
this.pageLimit = new int[]{start, end};
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected TableQueryBuilderImpl getThis() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.builder.impl;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.action.PreparedSQLUpdateActionImpl;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.PreparedSQLUpdateAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.builder.UpdateBuilder;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.manager.SQLManagerImpl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import static com.io.yutian.elementoriginlib.sql.api.SQLBuilder.withBackQuote;
|
|
||||||
|
|
||||||
public class UpdateBuilderImpl
|
|
||||||
extends AbstractConditionalBuilder<UpdateBuilder, SQLAction<Integer>>
|
|
||||||
implements UpdateBuilder {
|
|
||||||
|
|
||||||
protected final @NotNull String tableName;
|
|
||||||
|
|
||||||
@NotNull LinkedHashMap<String, Object> columnData;
|
|
||||||
|
|
||||||
public UpdateBuilderImpl(@NotNull SQLManagerImpl manager, @NotNull String tableName) {
|
|
||||||
super(manager);
|
|
||||||
this.tableName = tableName;
|
|
||||||
this.columnData = new LinkedHashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PreparedSQLUpdateAction<Integer> build() {
|
|
||||||
|
|
||||||
StringBuilder sqlBuilder = new StringBuilder();
|
|
||||||
|
|
||||||
sqlBuilder.append("UPDATE ").append(withBackQuote(getTableName())).append(" SET ");
|
|
||||||
|
|
||||||
Iterator<String> iterator = this.columnData.keySet().iterator();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
sqlBuilder.append(withBackQuote(iterator.next())).append(" = ?");
|
|
||||||
if (iterator.hasNext()) sqlBuilder.append(" , ");
|
|
||||||
}
|
|
||||||
List<Object> allParams = new ArrayList<>(this.columnData.values());
|
|
||||||
|
|
||||||
if (hasConditions()) {
|
|
||||||
sqlBuilder.append(" ").append(buildConditionSQL());
|
|
||||||
allParams.addAll(getConditionParams());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (limit > 0) sqlBuilder.append(" ").append(buildLimitSQL());
|
|
||||||
|
|
||||||
return new PreparedSQLUpdateActionImpl<>(getManager(), Integer.class, sqlBuilder.toString(), allParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getTableName() {
|
|
||||||
return tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UpdateBuilder addColumnValue(@NotNull String columnName, Object columnValue) {
|
|
||||||
Objects.requireNonNull(columnName, "columnName could not be null");
|
|
||||||
this.columnData.put(columnName, columnValue);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UpdateBuilder setColumnValues(LinkedHashMap<String, Object> columnData) {
|
|
||||||
this.columnData = columnData;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UpdateBuilder setColumnValues(@NotNull String[] columnNames, @Nullable Object[] columnValues) {
|
|
||||||
Objects.requireNonNull(columnNames, "columnName could not be null");
|
|
||||||
if (columnNames.length != columnValues.length) {
|
|
||||||
throw new RuntimeException("columnNames are not match with columnValues");
|
|
||||||
}
|
|
||||||
LinkedHashMap<String, Object> columnData = new LinkedHashMap<>();
|
|
||||||
for (int i = 0; i < columnNames.length; i++) {
|
|
||||||
columnData.put(columnNames[i], columnValues[i]);
|
|
||||||
}
|
|
||||||
return setColumnValues(columnData);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected UpdateBuilder getThis() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,254 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.manager;
|
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.sql.action.PreparedSQLBatchUpdateActionImpl;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.action.PreparedSQLUpdateActionImpl;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.action.SQLUpdateActionImpl;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.action.SQLUpdateBatchActionImpl;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLManager;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.SQLQuery;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.PreparedSQLUpdateAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.PreparedSQLUpdateBatchAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.action.SQLUpdateBatchAction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.builder.*;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLBiFunction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLDebugHandler;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLExceptionHandler;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.api.function.SQLFunction;
|
|
||||||
import com.io.yutian.elementoriginlib.sql.builder.impl.*;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DatabaseMetaData;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public class SQLManagerImpl implements SQLManager {
|
|
||||||
|
|
||||||
private final Logger LOGGER;
|
|
||||||
private final DataSource dataSource;
|
|
||||||
private final ConcurrentHashMap<UUID, SQLQuery> activeQuery = new ConcurrentHashMap<>();
|
|
||||||
protected ExecutorService executorPool;
|
|
||||||
@NotNull Supplier<Boolean> debugMode = () -> Boolean.FALSE;
|
|
||||||
|
|
||||||
@NotNull SQLExceptionHandler exceptionHandler;
|
|
||||||
@NotNull SQLDebugHandler debugHandler;
|
|
||||||
|
|
||||||
public SQLManagerImpl(@NotNull DataSource dataSource) {
|
|
||||||
this(dataSource, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SQLManagerImpl(@NotNull DataSource dataSource, @Nullable String name) {
|
|
||||||
this(dataSource, LoggerFactory.getLogger(SQLManagerImpl.class), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SQLManagerImpl(@NotNull DataSource dataSource, @NotNull Logger logger, @Nullable String name) {
|
|
||||||
String managerName = "SQLManager" + (name != null ? "#" + name : "");
|
|
||||||
this.LOGGER = logger;
|
|
||||||
this.dataSource = dataSource;
|
|
||||||
this.executorPool = SQLManager.defaultExecutorPool(managerName);
|
|
||||||
this.exceptionHandler = SQLExceptionHandler.detailed(getLogger());
|
|
||||||
this.debugHandler = SQLDebugHandler.defaultHandler(getLogger());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDebugMode() {
|
|
||||||
return this.debugMode.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDebugMode(@NotNull Supplier<@NotNull Boolean> debugMode) {
|
|
||||||
this.debugMode = debugMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull SQLDebugHandler getDebugHandler() {
|
|
||||||
return this.debugHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDebugHandler(@NotNull SQLDebugHandler debugHandler) {
|
|
||||||
this.debugHandler = debugHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Logger getLogger() {
|
|
||||||
return LOGGER;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull ExecutorService getExecutorPool() {
|
|
||||||
return executorPool;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setExecutorPool(@NotNull ExecutorService executorPool) {
|
|
||||||
this.executorPool = executorPool;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull DataSource getDataSource() {
|
|
||||||
return this.dataSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Connection getConnection() throws SQLException {
|
|
||||||
return getDataSource().getConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Map<UUID, SQLQuery> getActiveQuery() {
|
|
||||||
return this.activeQuery;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull SQLExceptionHandler getExceptionHandler() {
|
|
||||||
return this.exceptionHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setExceptionHandler(@Nullable SQLExceptionHandler handler) {
|
|
||||||
if (handler == null) this.exceptionHandler = SQLExceptionHandler.detailed(getLogger());
|
|
||||||
else this.exceptionHandler = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer executeSQL(String sql) {
|
|
||||||
return new SQLUpdateActionImpl<>(this, Integer.class, sql).execute(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer executeSQL(String sql, Object[] params) {
|
|
||||||
return new PreparedSQLUpdateActionImpl<>(this, Integer.class, sql, params).execute(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Integer> executeSQLBatch(String sql, Iterable<Object[]> paramsBatch) {
|
|
||||||
return new PreparedSQLBatchUpdateActionImpl<>(this, Integer.class, sql).setAllParams(paramsBatch).execute(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Integer> executeSQLBatch(@NotNull String sql, String... moreSQL) {
|
|
||||||
SQLUpdateBatchAction action = new SQLUpdateBatchActionImpl(this, sql);
|
|
||||||
if (moreSQL != null && moreSQL.length > 0) {
|
|
||||||
Arrays.stream(moreSQL).forEach(action::addBatch);
|
|
||||||
}
|
|
||||||
return action.execute(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable List<Integer> executeSQLBatch(@NotNull Iterable<String> sqlBatch) {
|
|
||||||
Iterator<String> iterator = sqlBatch.iterator();
|
|
||||||
if (!iterator.hasNext()) return null; // PLEASE GIVE IT SOMETHING
|
|
||||||
|
|
||||||
SQLUpdateBatchAction action = new SQLUpdateBatchActionImpl(this, iterator.next());
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
action.addBatch(iterator.next());
|
|
||||||
}
|
|
||||||
|
|
||||||
return action.execute(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <R> CompletableFuture<R> fetchMetadata(@NotNull SQLBiFunction<DatabaseMetaData, Connection, R> reader) {
|
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
|
||||||
try (Connection conn = getConnection()) {
|
|
||||||
return reader.apply(conn.getMetaData(), conn);
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
throw new RuntimeException(ex);
|
|
||||||
}
|
|
||||||
}, this.executorPool);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <R> CompletableFuture<R> fetchMetadata(@NotNull SQLBiFunction<DatabaseMetaData, Connection, ResultSet> supplier,
|
|
||||||
@NotNull SQLFunction<@NotNull ResultSet, R> reader) {
|
|
||||||
return fetchMetadata((meta, conn) -> {
|
|
||||||
try (ResultSet rs = supplier.apply(conn.getMetaData(), conn)) {
|
|
||||||
if (rs == null) throw new NullPointerException("Metadata返回的ResultSet为null。");
|
|
||||||
else return reader.apply(rs);
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
throw new RuntimeException(ex);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableCreateBuilder createTable(@NotNull String tableName) {
|
|
||||||
return new TableCreateBuilderImpl(this, tableName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableAlterBuilder alterTable(@NotNull String tableName) {
|
|
||||||
return new TableAlterBuilderImpl(this, tableName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TableMetadataBuilder fetchTableMetadata(@NotNull String tablePattern) {
|
|
||||||
return new TableMetadataBuilderImpl(this, tablePattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public QueryBuilder createQuery() {
|
|
||||||
return new QueryBuilderImpl(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InsertBuilder<PreparedSQLUpdateBatchAction<Integer>> createInsertBatch(@NotNull String tableName) {
|
|
||||||
return new InsertBuilderImpl<PreparedSQLUpdateBatchAction<Integer>>(this, tableName) {
|
|
||||||
@Override
|
|
||||||
public PreparedSQLUpdateBatchAction<Integer> setColumnNames(List<String> columnNames) {
|
|
||||||
return new PreparedSQLBatchUpdateActionImpl<>(getManager(), Integer.class, buildSQL(getTableName(), isIgnore(), columnNames));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InsertBuilder<PreparedSQLUpdateAction<Integer>> createInsert(@NotNull String tableName) {
|
|
||||||
return new InsertBuilderImpl<PreparedSQLUpdateAction<Integer>>(this, tableName) {
|
|
||||||
@Override
|
|
||||||
public PreparedSQLUpdateAction<Integer> setColumnNames(List<String> columnNames) {
|
|
||||||
return new PreparedSQLUpdateActionImpl<>(getManager(), Integer.class, buildSQL(getTableName(), isIgnore(), columnNames));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReplaceBuilder<PreparedSQLUpdateBatchAction<Integer>> createReplaceBatch(@NotNull String tableName) {
|
|
||||||
return new ReplaceBuilderImpl<PreparedSQLUpdateBatchAction<Integer>>(this, tableName) {
|
|
||||||
@Override
|
|
||||||
public PreparedSQLUpdateBatchAction<Integer> setColumnNames(List<String> columnNames) {
|
|
||||||
return new PreparedSQLBatchUpdateActionImpl<>(getManager(), Integer.class, buildSQL(getTableName(), columnNames));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReplaceBuilder<PreparedSQLUpdateAction<Integer>> createReplace(@NotNull String tableName) {
|
|
||||||
return new ReplaceBuilderImpl<PreparedSQLUpdateAction<Integer>>(this, tableName) {
|
|
||||||
@Override
|
|
||||||
public PreparedSQLUpdateAction<Integer> setColumnNames(List<String> columnNames) {
|
|
||||||
return new PreparedSQLUpdateActionImpl<>(getManager(), Integer.class, buildSQL(getTableName(), columnNames));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UpdateBuilder createUpdate(@NotNull String tableName) {
|
|
||||||
return new UpdateBuilderImpl(this, tableName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DeleteBuilder createDelete(@NotNull String tableName) {
|
|
||||||
return new DeleteBuilderImpl(this, tableName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.util;
|
|
||||||
|
|
||||||
public enum DatabaseDriverType {
|
|
||||||
|
|
||||||
MYSQL("com.mysql.jdbc.Driver"),
|
|
||||||
MYSQL_CJ("com.mysql.cj.jdbc.Driver"),
|
|
||||||
SQLITE("org.sqlite.JDBC"),
|
|
||||||
H2("org.h2.Driver");
|
|
||||||
|
|
||||||
private String driverClassName;
|
|
||||||
|
|
||||||
DatabaseDriverType(String driverClassName) {
|
|
||||||
this.driverClassName = driverClassName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDriverClassName() {
|
|
||||||
return driverClassName;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,210 +0,0 @@
|
||||||
package com.io.yutian.elementoriginlib.sql.util;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.sql.*;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class StatementUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建一个 {@link PreparedStatement} 。
|
|
||||||
*
|
|
||||||
* @param connection 数据库连接
|
|
||||||
* @param sql SQL语句,使用"?"做为占位符
|
|
||||||
* @param params "?"所代表的对应参数列表
|
|
||||||
* @return 完成参数填充的 {@link PreparedStatement}
|
|
||||||
*/
|
|
||||||
public static PreparedStatement createPrepareStatement(
|
|
||||||
Connection connection, String sql, Object[] params
|
|
||||||
) throws SQLException {
|
|
||||||
return createPrepareStatement(connection, sql, params, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建一个 {@link PreparedStatement} 。
|
|
||||||
*
|
|
||||||
* @param connection 数据库连接
|
|
||||||
* @param sql SQL语句,使用"?"做为占位符
|
|
||||||
* @param params "?"所代表的对应参数列表
|
|
||||||
* @param returnGeneratedKey 是否会返回自增主键
|
|
||||||
* @return 完成参数填充的 {@link PreparedStatement}
|
|
||||||
*/
|
|
||||||
public static PreparedStatement createPrepareStatement(
|
|
||||||
Connection connection, String sql, Object[] params, boolean returnGeneratedKey
|
|
||||||
) throws SQLException {
|
|
||||||
sql = sql.trim();
|
|
||||||
PreparedStatement statement = connection.prepareStatement(sql, returnGeneratedKey ? Statement.RETURN_GENERATED_KEYS : Statement.NO_GENERATED_KEYS);
|
|
||||||
Map<Integer, Integer> nullTypeMap = new HashMap<>();
|
|
||||||
if (params != null) fillParams(statement, Arrays.asList(params), nullTypeMap);
|
|
||||||
statement.addBatch();
|
|
||||||
return statement;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建批量操作的一个 {@link PreparedStatement} 。
|
|
||||||
*
|
|
||||||
* @param connection 数据库连接
|
|
||||||
* @param sql SQL语句,使用"?"做为占位符
|
|
||||||
* @param paramsBatch "?"所代表的对应参数列表
|
|
||||||
* @return 完成参数填充的 {@link PreparedStatement}
|
|
||||||
*/
|
|
||||||
public static PreparedStatement createPrepareStatementBatch(
|
|
||||||
Connection connection, String sql, Iterable<Object[]> paramsBatch
|
|
||||||
) throws SQLException {
|
|
||||||
return createPrepareStatementBatch(connection, sql, paramsBatch, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建批量操作的一个 {@link PreparedStatement} 。
|
|
||||||
*
|
|
||||||
* @param connection 数据库连接
|
|
||||||
* @param sql SQL语句,使用"?"做为占位符
|
|
||||||
* @param paramsBatch "?"所代表的对应参数列表
|
|
||||||
* @param returnGeneratedKey 是否会返回自增主键
|
|
||||||
* @return 完成参数填充的 {@link PreparedStatement}
|
|
||||||
*/
|
|
||||||
public static PreparedStatement createPrepareStatementBatch(
|
|
||||||
Connection connection, String sql, Iterable<Object[]> paramsBatch, boolean returnGeneratedKey
|
|
||||||
) throws SQLException {
|
|
||||||
|
|
||||||
sql = sql.trim();
|
|
||||||
PreparedStatement statement = connection.prepareStatement(sql, returnGeneratedKey ? Statement.RETURN_GENERATED_KEYS : Statement.NO_GENERATED_KEYS);
|
|
||||||
Map<Integer, Integer> nullTypeMap = new HashMap<>();
|
|
||||||
for (Object[] params : paramsBatch) {
|
|
||||||
fillParams(statement, Arrays.asList(params), nullTypeMap);
|
|
||||||
statement.addBatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
return statement;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 填充PreparedStatement的参数。
|
|
||||||
*
|
|
||||||
* @param statement PreparedStatement
|
|
||||||
* @param params SQL参数
|
|
||||||
* @return {@link PreparedStatement} 填充参数后的PreparedStatement
|
|
||||||
* @throws SQLException SQL执行异常
|
|
||||||
*/
|
|
||||||
public static PreparedStatement fillParams(
|
|
||||||
PreparedStatement statement, Iterable<?> params
|
|
||||||
) throws SQLException {
|
|
||||||
return fillParams(statement, params, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 填充PreparedStatement的参数。
|
|
||||||
*
|
|
||||||
* @param statement PreparedStatement
|
|
||||||
* @param params SQL参数
|
|
||||||
* @param nullCache null参数的类型缓存,避免循环中重复获取类型
|
|
||||||
* @return 完成参数填充的 {@link PreparedStatement}
|
|
||||||
*/
|
|
||||||
public static PreparedStatement fillParams(
|
|
||||||
PreparedStatement statement, Iterable<?> params, Map<Integer, Integer> nullCache
|
|
||||||
) throws SQLException {
|
|
||||||
if (null == params) {
|
|
||||||
return statement;// 无参数
|
|
||||||
}
|
|
||||||
|
|
||||||
int paramIndex = 1;//第一个参数从1计数
|
|
||||||
for (Object param : params) {
|
|
||||||
setParam(statement, paramIndex++, param, nullCache);
|
|
||||||
}
|
|
||||||
return statement;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取null字段对应位置的数据类型
|
|
||||||
* 如果类型获取失败将使用默认的 {@link Types#VARCHAR}
|
|
||||||
*
|
|
||||||
* @param statement {@link PreparedStatement}
|
|
||||||
* @param paramIndex 参数序列,第一位从1开始
|
|
||||||
* @return 数据类型,默认为 {@link Types#VARCHAR}
|
|
||||||
*/
|
|
||||||
public static int getNullType(PreparedStatement statement, int paramIndex) {
|
|
||||||
try {
|
|
||||||
ParameterMetaData pmd = statement.getParameterMetaData();
|
|
||||||
return pmd.getParameterType(paramIndex);
|
|
||||||
} catch (SQLException ignore) {
|
|
||||||
return Types.VARCHAR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为 {@link PreparedStatement} 设置单个参数
|
|
||||||
*
|
|
||||||
* @param preparedStatement {@link PreparedStatement}
|
|
||||||
* @param paramIndex 参数序列,从1开始
|
|
||||||
* @param param 参数,不能为{@code null}
|
|
||||||
* @param nullCache 用于缓存参数为null位置的类型,避免重复获取
|
|
||||||
*/
|
|
||||||
private static void setParam(
|
|
||||||
PreparedStatement preparedStatement, int paramIndex, Object param,
|
|
||||||
Map<Integer, Integer> nullCache
|
|
||||||
) throws SQLException {
|
|
||||||
|
|
||||||
if (param == null) {
|
|
||||||
Integer type = (null == nullCache) ? null : nullCache.get(paramIndex);
|
|
||||||
if (null == type) {
|
|
||||||
type = getNullType(preparedStatement, paramIndex);
|
|
||||||
if (null != nullCache) {
|
|
||||||
nullCache.put(paramIndex, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
preparedStatement.setNull(paramIndex, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 针对UUID特殊处理,避免元数据直接传入
|
|
||||||
if (param instanceof UUID) {
|
|
||||||
preparedStatement.setString(paramIndex, param.toString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 针对StringBuilder或StringBuffer进行处理,避免元数据传入
|
|
||||||
if (param instanceof StringBuilder || param instanceof StringBuffer) {
|
|
||||||
preparedStatement.setString(paramIndex, param.toString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 日期特殊处理,默认按照时间戳传入,避免精度丢失
|
|
||||||
if (param instanceof java.util.Date) {
|
|
||||||
if (param instanceof Date) {
|
|
||||||
preparedStatement.setDate(paramIndex, (Date) param);
|
|
||||||
} else if (param instanceof Time) {
|
|
||||||
preparedStatement.setTime(paramIndex, (Time) param);
|
|
||||||
} else {
|
|
||||||
preparedStatement.setTimestamp(paramIndex, new Timestamp(((java.util.Date) param).getTime()));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 针对大数字类型的特殊处理
|
|
||||||
if (param instanceof Number) {
|
|
||||||
if (param instanceof BigDecimal) {
|
|
||||||
// BigDecimal的转换交给JDBC驱动处理
|
|
||||||
preparedStatement.setBigDecimal(paramIndex, (BigDecimal) param);
|
|
||||||
return;
|
|
||||||
} else if (param instanceof BigInteger) {
|
|
||||||
preparedStatement.setBigDecimal(paramIndex, new BigDecimal((BigInteger) param));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 其它数字类型按照默认类型传入
|
|
||||||
}
|
|
||||||
|
|
||||||
if (param instanceof Enum) {
|
|
||||||
//枚举类采用 name()
|
|
||||||
preparedStatement.setString(paramIndex, ((Enum<?>) param).name());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 其它参数类型直接传入
|
|
||||||
preparedStatement.setObject(paramIndex, param);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.io.yutian.elementoriginlib.util;
|
package com.io.yutian.elementoriginlib.util;
|
||||||
|
|
||||||
import com.io.yutian.elementoriginlib.nbt.NBTCompound;
|
import com.io.yutian.elementoriginlib.nbt.TagCompound;
|
||||||
import com.io.yutian.elementoriginlib.nbt.NBTItem;
|
import com.io.yutian.elementoriginlib.nbt.NBTItem;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
@ -47,9 +47,9 @@ public class ItemStackUtil {
|
||||||
}
|
}
|
||||||
NBTItem nbtOriginal = new NBTItem(original);
|
NBTItem nbtOriginal = new NBTItem(original);
|
||||||
NBTItem nbtTester = new NBTItem(tester);
|
NBTItem nbtTester = new NBTItem(tester);
|
||||||
NBTCompound nbtCompound0 = nbtOriginal.getTag();
|
TagCompound tagCompound0 = nbtOriginal.getTag();
|
||||||
NBTCompound nbtCompound1 = nbtTester.getTag();
|
TagCompound tagCompound1 = nbtTester.getTag();
|
||||||
return nbtCompound0.equals(nbtCompound1);
|
return tagCompound0.equals(tagCompound1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int countItems(Inventory inventory, @NotNull ItemStack item) {
|
public static int countItems(Inventory inventory, @NotNull ItemStack item) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user