1
mirror of https://github.com/CarmJos/EasySQL.git synced 2024-09-19 13:25:47 +00:00

feat(metadata): 新增数个常用Metadata读取操作方法。

This commit is contained in:
Carm Jos 2022-08-17 03:16:49 +08:00
parent 5e41e21385
commit fc0a3e9754
5 changed files with 132 additions and 19 deletions

View File

@ -5,6 +5,7 @@ import cc.carm.lib.easysql.api.action.PreparedSQLUpdateBatchAction;
import cc.carm.lib.easysql.api.action.SQLUpdateAction;
import cc.carm.lib.easysql.api.action.SQLUpdateBatchAction;
import cc.carm.lib.easysql.api.builder.*;
import cc.carm.lib.easysql.api.function.SQLBiFunction;
import cc.carm.lib.easysql.api.function.SQLDebugHandler;
import cc.carm.lib.easysql.api.function.SQLExceptionHandler;
import cc.carm.lib.easysql.api.function.SQLFunction;
@ -187,11 +188,13 @@ public interface SQLManager {
/**
* 获取并操作 {@link DatabaseMetaData} 以得到需要的数据库消息
*
* @param metadata 操作与返回的方法
* @param <R> 最终结果的返回类型
* @param reader 操作与读取的方法
* @param <R> 最终结果的返回类型
* @return 最终结果通过 {@link CompletableFuture#get()} 可阻塞并等待结果返回
*/
<R> CompletableFuture<R> fetchMetadata(@NotNull SQLFunction<DatabaseMetaData, R> metadata);
default <R> CompletableFuture<R> fetchMetadata(@NotNull SQLFunction<DatabaseMetaData, R> reader) {
return fetchMetadata((meta, conn) -> reader.apply(meta));
}
/**
* 获取并操作 {@link DatabaseMetaData} 提供的指定 {@link ResultSet} 以得到需要的数据库消息
@ -203,7 +206,31 @@ public interface SQLManager {
* @return 最终结果通过 {@link CompletableFuture#get()} 可阻塞并等待结果返回
* @throws NullPointerException supplier 提供的 {@link ResultSet} 为NULL时抛出
*/
<R> CompletableFuture<R> fetchMetadata(@NotNull SQLFunction<DatabaseMetaData, ResultSet> supplier,
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);
/**

View File

@ -1,7 +1,13 @@
package cc.carm.lib.easysql.api.builder;
import cc.carm.lib.easysql.api.SQLBuilder;
import cc.carm.lib.easysql.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 {
@ -12,10 +18,38 @@ public interface TableMetadataBuilder extends SQLBuilder {
CompletableFuture<Boolean> validateExist();
/**
* @param columnName 需要判断的列名
* 对表内的数据列元数据进行读取
*
* @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(String columnName);
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.

View File

@ -0,0 +1,24 @@
package cc.carm.lib.easysql.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);
};
}
}

View File

@ -1,13 +1,20 @@
package cc.carm.lib.easysql.builder.impl;
import cc.carm.lib.easysql.api.builder.TableMetadataBuilder;
import cc.carm.lib.easysql.api.function.SQLBiFunction;
import cc.carm.lib.easysql.api.function.SQLFunction;
import cc.carm.lib.easysql.builder.AbstractSQLBuilder;
import cc.carm.lib.easysql.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
@ -23,12 +30,35 @@ public class TableMetadataBuilderImpl
@Override
public CompletableFuture<Boolean> validateExist() {
return validate((meta) -> meta.getTables(null, null, tablePattern, new String[]{"TABLE"}));
return validate((meta, conn) -> meta.getTables(conn.getCatalog(), conn.getSchema(), tablePattern.toUpperCase(), new String[]{"TABLE"}));
}
@Override
public CompletableFuture<Boolean> isColumnExists(String columnPattern) {
return validate((meta) -> meta.getColumns(null, null, tablePattern, columnPattern));
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);
});
}
/**
@ -37,7 +67,7 @@ public class TableMetadataBuilderImpl
* @param supplier supplier to get result set
* @return result future
*/
private CompletableFuture<Boolean> validate(SQLFunction<DatabaseMetaData, ResultSet> supplier) {
private CompletableFuture<Boolean> validate(SQLBiFunction<DatabaseMetaData, Connection, ResultSet> supplier) {
return getManager().fetchMetadata(supplier, ResultSet::next);
}

View File

@ -10,6 +10,7 @@ import cc.carm.lib.easysql.api.action.PreparedSQLUpdateAction;
import cc.carm.lib.easysql.api.action.PreparedSQLUpdateBatchAction;
import cc.carm.lib.easysql.api.action.SQLUpdateBatchAction;
import cc.carm.lib.easysql.api.builder.*;
import cc.carm.lib.easysql.api.function.SQLBiFunction;
import cc.carm.lib.easysql.api.function.SQLDebugHandler;
import cc.carm.lib.easysql.api.function.SQLExceptionHandler;
import cc.carm.lib.easysql.api.function.SQLFunction;
@ -155,10 +156,10 @@ public class SQLManagerImpl implements SQLManager {
}
@Override
public <R> CompletableFuture<R> fetchMetadata(@NotNull SQLFunction<DatabaseMetaData, R> metadata) {
public <R> CompletableFuture<R> fetchMetadata(@NotNull SQLBiFunction<DatabaseMetaData, Connection, R> reader) {
return CompletableFuture.supplyAsync(() -> {
try (Connection conn = getConnection()) {
return metadata.apply(conn.getMetaData());
return reader.apply(conn.getMetaData(), conn);
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
@ -166,19 +167,16 @@ public class SQLManagerImpl implements SQLManager {
}
@Override
public <R> CompletableFuture<R> fetchMetadata(@NotNull SQLFunction<DatabaseMetaData, ResultSet> supplier,
public <R> CompletableFuture<R> fetchMetadata(@NotNull SQLBiFunction<DatabaseMetaData, Connection, ResultSet> supplier,
@NotNull SQLFunction<@NotNull ResultSet, R> reader) {
return CompletableFuture.supplyAsync(() -> {
try (
Connection conn = getConnection();
ResultSet rs = supplier.apply(conn.getMetaData())
) {
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);
}
}, this.executorPool);
});
}
@Override