From 054f9bb04c4b8c057b14ebdb2459c8f10e166769 Mon Sep 17 00:00:00 2001 From: carm Date: Tue, 3 Jan 2023 20:52:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(table):=20=E6=B7=BB=E5=8A=A0=E5=8D=95?= =?UTF-8?q?=E7=8B=AC=E7=9A=84=E8=A1=A8=E5=A3=B0=E6=98=8E=E7=B1=BB=E5=8F=8A?= =?UTF-8?q?=E5=BF=AB=E9=80=9F=E5=88=9D=E5=A7=8B=E5=8C=96=E8=A1=A8=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/pom.xml | 2 +- .../java/cc/carm/plugin/minesql/IMineSQL.java | 17 ++ .../java/cc/carm/plugin/minesql/MineSQL.java | 21 +++ .../minesql/api/table/SQLTablesRoot.java | 12 ++ .../minesql/api/table/SimpleSQLTable.java | 156 ++++++++++++++++++ core/pom.xml | 2 +- .../cc/carm/plugin/minesql/MineSQLCore.java | 46 ++++++ platforms/bukkit/pom.xml | 2 +- platforms/bungee/pom.xml | 2 +- platforms/velocity/pom.xml | 2 +- plugin/pom.xml | 2 +- pom.xml | 2 +- 12 files changed, 259 insertions(+), 7 deletions(-) create mode 100644 api/src/main/java/cc/carm/plugin/minesql/api/table/SQLTablesRoot.java create mode 100644 api/src/main/java/cc/carm/plugin/minesql/api/table/SimpleSQLTable.java diff --git a/api/pom.xml b/api/pom.xml index 5647259..11d6c62 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -5,7 +5,7 @@ minesql-parent cc.carm.plugin - 1.1.1 + 1.2.0 4.0.0 diff --git a/api/src/main/java/cc/carm/plugin/minesql/IMineSQL.java b/api/src/main/java/cc/carm/plugin/minesql/IMineSQL.java index cbf04f2..3882cf3 100644 --- a/api/src/main/java/cc/carm/plugin/minesql/IMineSQL.java +++ b/api/src/main/java/cc/carm/plugin/minesql/IMineSQL.java @@ -4,11 +4,14 @@ import cc.carm.lib.easysql.api.SQLManager; import cc.carm.lib.easysql.api.SQLQuery; import cc.carm.plugin.minesql.api.SQLRegistry; import cc.carm.plugin.minesql.api.source.SQLSourceConfig; +import cc.carm.plugin.minesql.api.table.SQLTablesRoot; +import cc.carm.plugin.minesql.api.table.SimpleSQLTable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.sql.DataSource; import java.io.File; +import java.sql.SQLException; import java.util.Map; import java.util.Properties; import java.util.UUID; @@ -61,4 +64,18 @@ interface IMineSQL { */ void shutdown(SQLManager manager, @Nullable Consumer> activeQueries); + /** + * 读取一个 {@link SQLTablesRoot} 中全部的 {@link SimpleSQLTable} 实例并初始化。 + * + * @param tablesRoot {@link SQLTablesRoot}实例 + */ + void createTables(@NotNull SQLTablesRoot tablesRoot) throws Exception; + + /** + * 读取一个 {@link SQLTablesRoot}类中 中全部的静态 {@link SimpleSQLTable} 实例并初始化。 + * + * @param tablesRootClazz {@link SQLTablesRoot}静态类 + */ + void createTables(@NotNull Class tablesRootClazz) throws Exception; + } diff --git a/api/src/main/java/cc/carm/plugin/minesql/MineSQL.java b/api/src/main/java/cc/carm/plugin/minesql/MineSQL.java index e3bdc1d..9120f55 100644 --- a/api/src/main/java/cc/carm/plugin/minesql/MineSQL.java +++ b/api/src/main/java/cc/carm/plugin/minesql/MineSQL.java @@ -4,6 +4,8 @@ import cc.carm.lib.easysql.api.SQLManager; import cc.carm.lib.easysql.api.SQLQuery; import cc.carm.plugin.minesql.api.SQLRegistry; import cc.carm.plugin.minesql.api.source.SQLSourceConfig; +import cc.carm.plugin.minesql.api.table.SQLTablesRoot; +import cc.carm.plugin.minesql.api.table.SimpleSQLTable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -114,4 +116,23 @@ public class MineSQL { shutdown(manager, true); } + + /** + * 读取一个 {@link SQLTablesRoot} 中全部的 {@link SimpleSQLTable} 实例并初始化。 + * + * @param tablesRoot {@link SQLTablesRoot}实例 + */ + public static void createTables(@NotNull SQLTablesRoot tablesRoot) throws Exception { + instance.createTables(tablesRoot); + } + + /** + * 读取一个 {@link SQLTablesRoot}类中 中全部的静态 {@link SimpleSQLTable} 实例并初始化。 + * + * @param tablesRootClazz {@link SQLTablesRoot}静态类 + */ + public static void createTables(@NotNull Class tablesRootClazz) throws Exception { + instance.createTables(tablesRootClazz); + } + } diff --git a/api/src/main/java/cc/carm/plugin/minesql/api/table/SQLTablesRoot.java b/api/src/main/java/cc/carm/plugin/minesql/api/table/SQLTablesRoot.java new file mode 100644 index 0000000..666e804 --- /dev/null +++ b/api/src/main/java/cc/carm/plugin/minesql/api/table/SQLTablesRoot.java @@ -0,0 +1,12 @@ +package cc.carm.plugin.minesql.api.table; + +import cc.carm.lib.easysql.api.function.SQLHandler; + +import java.util.function.Supplier; + +/** + * 表声明类的根节点,用于标注该类用于记录表的结构信息。 + *
创建表请使用 {@link SimpleSQLTable#of(String, String, Supplier, SQLHandler)}。 + */ +public abstract class SQLTablesRoot { +} diff --git a/api/src/main/java/cc/carm/plugin/minesql/api/table/SimpleSQLTable.java b/api/src/main/java/cc/carm/plugin/minesql/api/table/SimpleSQLTable.java new file mode 100644 index 0000000..44dc97f --- /dev/null +++ b/api/src/main/java/cc/carm/plugin/minesql/api/table/SimpleSQLTable.java @@ -0,0 +1,156 @@ +package cc.carm.plugin.minesql.api.table; + +import cc.carm.lib.easysql.api.SQLManager; +import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction; +import cc.carm.lib.easysql.api.action.PreparedSQLUpdateBatchAction; +import cc.carm.lib.easysql.api.builder.*; +import cc.carm.lib.easysql.api.function.SQLHandler; +import cc.carm.plugin.minesql.MineSQL; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.sql.SQLException; +import java.util.Optional; +import java.util.function.Supplier; + +public class SimpleSQLTable { + + public static @NotNull SimpleSQLTable of(@NotNull String tableName, + @NotNull SQLHandler tableBuilder) { + return new SimpleSQLTable(null, tableName, null, tableBuilder); + } + + public static @NotNull SimpleSQLTable of(@Nullable String database, @NotNull String tableName, + @NotNull SQLHandler tableBuilder) { + return new SimpleSQLTable(database, tableName, null, tableBuilder); + } + + public static @NotNull SimpleSQLTable of(@Nullable String database, @NotNull String tableName, + @Nullable String tablePrefix, @NotNull SQLHandler tableBuilder) { + return new SimpleSQLTable(database, tableName, () -> tablePrefix, tableBuilder); + } + + public static @NotNull SimpleSQLTable of(@Nullable String database, @NotNull String tableName, + @Nullable Supplier tablePrefix, @NotNull SQLHandler tableBuilder) { + return new SimpleSQLTable(database, tableName, tablePrefix, tableBuilder); + } + + protected final @Nullable String database; + protected final @NotNull String tableName; + + protected final @Nullable Supplier tablePrefix; + protected final @NotNull SQLHandler tableCreator; + + public SimpleSQLTable(@Nullable String database, @NotNull String tableName, + @Nullable Supplier tablePrefix, @NotNull SQLHandler table) { + this.database = database; + this.tableName = tableName; + this.tablePrefix = tablePrefix; + this.tableCreator = table; + } + + public boolean create() throws SQLException { + SQLManager sqlManager = getSQLManager(); + if (sqlManager == null) throw new SQLException(getExceptionReason()); + + TableCreateBuilder tableBuilder = sqlManager.createTable(getTableName()); + tableCreator.accept(tableBuilder); + return tableBuilder.build().executeFunction(l -> l > 0, false); + } + + public @Nullable String getDatabase() { + return database; + } + + public @Nullable SQLManager getSQLManager() { + return MineSQL.getRegistry().get(getDatabase()); + } + + public @NotNull String getTableName() { + String prefix = getTablePrefix(); + return (prefix != null ? prefix : "") + tableName; + } + + public @Nullable String getTablePrefix() { + return Optional.ofNullable(tablePrefix).map(Supplier::get).orElse(null); + } + + public @NotNull TableQueryBuilder createQuery() { + return Optional.ofNullable(getSQLManager()).map(this::createQuery) + .orElseThrow(() -> new NullPointerException(getExceptionReason())); + } + + public @NotNull TableQueryBuilder createQuery(@NotNull SQLManager sqlManager) { + return sqlManager.createQuery().inTable(getTableName()); + } + + public @NotNull DeleteBuilder createDelete() { + return Optional.ofNullable(getSQLManager()).map(this::createDelete) + .orElseThrow(() -> new NullPointerException(getExceptionReason())); + } + + public @NotNull DeleteBuilder createDelete(@NotNull SQLManager sqlManager) { + return sqlManager.createDelete(getTableName()); + } + + public @NotNull UpdateBuilder createUpdate() { + return Optional.ofNullable(getSQLManager()).map(this::createUpdate) + .orElseThrow(() -> new NullPointerException(getExceptionReason())); + } + + public @NotNull UpdateBuilder createUpdate(@NotNull SQLManager sqlManager) { + return sqlManager.createUpdate(getTableName()); + } + + public @NotNull InsertBuilder> createInsert() { + return Optional.ofNullable(getSQLManager()).map(this::createInsert) + .orElseThrow(() -> new NullPointerException(getExceptionReason())); + } + + public @NotNull InsertBuilder> createInsert(@NotNull SQLManager sqlManager) { + return sqlManager.createInsert(getTableName()); + } + + public @NotNull InsertBuilder> createInsertBatch() { + return Optional.ofNullable(getSQLManager()).map(this::createInsertBatch) + .orElseThrow(() -> new NullPointerException(getExceptionReason())); + } + + public @NotNull InsertBuilder> createInsertBatch(@NotNull SQLManager sqlManager) { + return sqlManager.createInsertBatch(getTableName()); + } + + public @NotNull ReplaceBuilder> createReplace() { + return Optional.ofNullable(getSQLManager()).map(this::createReplace) + .orElseThrow(() -> new NullPointerException(getExceptionReason())); + + } + + public @NotNull ReplaceBuilder> createReplace(@NotNull SQLManager sqlManager) { + return sqlManager.createReplace(getTableName()); + } + + public @NotNull ReplaceBuilder> createReplaceBatch() { + return Optional.ofNullable(getSQLManager()).map(this::createReplaceBatch) + .orElseThrow(() -> new NullPointerException(getExceptionReason())); + } + + public @NotNull ReplaceBuilder> createReplaceBatch(@NotNull SQLManager sqlManager) { + return sqlManager.createReplaceBatch(getTableName()); + } + + public @NotNull TableAlterBuilder alter() { + return Optional.ofNullable(getSQLManager()).map(this::alter) + .orElseThrow(() -> new NullPointerException(getExceptionReason())); + } + + public @NotNull TableAlterBuilder alter(@NotNull SQLManager sqlManager) { + return sqlManager.alterTable(getTableName()); + } + + private String getExceptionReason() { + if (getDatabase() == null) return "Cannot find any SQLManager."; + else return "Cannot find any SQLManager for \"" + getDatabase() + "\"."; + } + +} diff --git a/core/pom.xml b/core/pom.xml index dc5d85f..eea2822 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -5,7 +5,7 @@ minesql-parent cc.carm.plugin - 1.1.1 + 1.2.0 4.0.0 diff --git a/core/src/main/java/cc/carm/plugin/minesql/MineSQLCore.java b/core/src/main/java/cc/carm/plugin/minesql/MineSQLCore.java index eaae6f5..e0ec3de 100644 --- a/core/src/main/java/cc/carm/plugin/minesql/MineSQLCore.java +++ b/core/src/main/java/cc/carm/plugin/minesql/MineSQLCore.java @@ -8,6 +8,8 @@ import cc.carm.lib.easysql.api.SQLQuery; import cc.carm.lib.easysql.manager.SQLManagerImpl; import cc.carm.lib.githubreleases4j.GithubReleases4J; import cc.carm.plugin.minesql.api.source.SQLSourceConfig; +import cc.carm.plugin.minesql.api.table.SQLTablesRoot; +import cc.carm.plugin.minesql.api.table.SimpleSQLTable; import cc.carm.plugin.minesql.command.MineSQLCommand; import cc.carm.plugin.minesql.command.MineSQLHelpFormatter; import cc.carm.plugin.minesql.conf.PluginConfiguration; @@ -23,6 +25,8 @@ import org.jetbrains.annotations.Nullable; import javax.sql.DataSource; import java.io.File; +import java.lang.reflect.Field; +import java.sql.SQLException; import java.util.*; import java.util.function.Consumer; import java.util.logging.Logger; @@ -157,6 +161,48 @@ public class MineSQLCore implements IMineSQL { } } + @Override + public void createTables(@NotNull SQLTablesRoot tablesRoot) throws SQLException { + for (Field field : tablesRoot.getClass().getDeclaredFields()) { + initializeTableField(tablesRoot, field); + } + } + + @Override + public void createTables(@NotNull Class clazz) throws SQLException { + initializeTableClass(clazz); + } + + protected void initializeTableClass(@NotNull Class clazz) throws SQLException { + if (!SQLTablesRoot.class.isAssignableFrom(clazz)) return; + + for (Field field : clazz.getDeclaredFields()) { + initializeTableField(clazz, field); + } + + for (Class subClass : clazz.getDeclaredClasses()) { + initializeTableClass(subClass); + } + + } + + protected void initializeTableField(@NotNull Object source, @NotNull Field field) throws SQLException { + try { + field.setAccessible(true); + Object object = field.get(source); + + if (object instanceof SimpleSQLTable) { + ((SimpleSQLTable) object).create(); + } else if (source instanceof SQLTablesRoot && object instanceof SQLTablesRoot) { + createTables((SQLTablesRoot) object); + } else if (source instanceof Class && object instanceof Class) { + // 当且仅当 源字段与字段 均为静态类时,才对目标字段进行下一步初始化加载。 + initializeTableClass((Class) object); + } + } catch (IllegalAccessException ignored) { + } + } + public void shutdownAll() { this.registry.getManagers().forEach((k, manager) -> { getLogger().info(" 正在关闭数据库 " + k + "..."); diff --git a/platforms/bukkit/pom.xml b/platforms/bukkit/pom.xml index 2952251..9a36dba 100644 --- a/platforms/bukkit/pom.xml +++ b/platforms/bukkit/pom.xml @@ -5,7 +5,7 @@ minesql-parent cc.carm.plugin - 1.1.1 + 1.2.0 ../../pom.xml 4.0.0 diff --git a/platforms/bungee/pom.xml b/platforms/bungee/pom.xml index 1f9811b..002720f 100644 --- a/platforms/bungee/pom.xml +++ b/platforms/bungee/pom.xml @@ -5,7 +5,7 @@ minesql-parent cc.carm.plugin - 1.1.1 + 1.2.0 ../../pom.xml 4.0.0 diff --git a/platforms/velocity/pom.xml b/platforms/velocity/pom.xml index 6c1f082..be49d81 100644 --- a/platforms/velocity/pom.xml +++ b/platforms/velocity/pom.xml @@ -5,7 +5,7 @@ minesql-parent cc.carm.plugin - 1.1.1 + 1.2.0 ../../pom.xml 4.0.0 diff --git a/plugin/pom.xml b/plugin/pom.xml index c79f9a3..6f5ed0a 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -5,7 +5,7 @@ minesql-parent cc.carm.plugin - 1.1.1 + 1.2.0 4.0.0 diff --git a/pom.xml b/pom.xml index 3b7900f..6e7a061 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ cc.carm.plugin minesql-parent pom - 1.1.1 + 1.2.0 api core