mirror of
https://github.com/CarmJos/EasySQL.git
synced 2024-09-19 21:35:47 +00:00
feat(metadata): 新增数个常用Metadata读取操作方法。
This commit is contained in:
parent
5e41e21385
commit
fc0a3e9754
@ -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.SQLUpdateAction;
|
||||||
import cc.carm.lib.easysql.api.action.SQLUpdateBatchAction;
|
import cc.carm.lib.easysql.api.action.SQLUpdateBatchAction;
|
||||||
import cc.carm.lib.easysql.api.builder.*;
|
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.SQLDebugHandler;
|
||||||
import cc.carm.lib.easysql.api.function.SQLExceptionHandler;
|
import cc.carm.lib.easysql.api.function.SQLExceptionHandler;
|
||||||
import cc.carm.lib.easysql.api.function.SQLFunction;
|
import cc.carm.lib.easysql.api.function.SQLFunction;
|
||||||
@ -187,11 +188,13 @@ public interface SQLManager {
|
|||||||
/**
|
/**
|
||||||
* 获取并操作 {@link DatabaseMetaData} 以得到需要的数据库消息。
|
* 获取并操作 {@link DatabaseMetaData} 以得到需要的数据库消息。
|
||||||
*
|
*
|
||||||
* @param metadata 操作与返回的方法
|
* @param reader 操作与读取的方法
|
||||||
* @param <R> 最终结果的返回类型
|
* @param <R> 最终结果的返回类型
|
||||||
* @return 最终结果,通过 {@link CompletableFuture#get()} 可阻塞并等待结果返回。
|
* @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} 以得到需要的数据库消息。
|
* 获取并操作 {@link DatabaseMetaData} 提供的指定 {@link ResultSet} 以得到需要的数据库消息。
|
||||||
@ -203,7 +206,31 @@ public interface SQLManager {
|
|||||||
* @return 最终结果,通过 {@link CompletableFuture#get()} 可阻塞并等待结果返回。
|
* @return 最终结果,通过 {@link CompletableFuture#get()} 可阻塞并等待结果返回。
|
||||||
* @throws NullPointerException 当 supplier 提供的 {@link ResultSet} 为NULL时抛出
|
* @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);
|
@NotNull SQLFunction<@NotNull ResultSet, R> reader);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
package cc.carm.lib.easysql.api.builder;
|
package cc.carm.lib.easysql.api.builder;
|
||||||
|
|
||||||
import cc.carm.lib.easysql.api.SQLBuilder;
|
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;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public interface TableMetadataBuilder extends SQLBuilder {
|
public interface TableMetadataBuilder extends SQLBuilder {
|
||||||
@ -12,10 +18,38 @@ public interface TableMetadataBuilder extends SQLBuilder {
|
|||||||
CompletableFuture<Boolean> validateExist();
|
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 对应列是否存在
|
* @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.
|
// More coming soon.
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,13 +1,20 @@
|
|||||||
package cc.carm.lib.easysql.builder.impl;
|
package cc.carm.lib.easysql.builder.impl;
|
||||||
|
|
||||||
import cc.carm.lib.easysql.api.builder.TableMetadataBuilder;
|
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.api.function.SQLFunction;
|
||||||
import cc.carm.lib.easysql.builder.AbstractSQLBuilder;
|
import cc.carm.lib.easysql.builder.AbstractSQLBuilder;
|
||||||
import cc.carm.lib.easysql.manager.SQLManagerImpl;
|
import cc.carm.lib.easysql.manager.SQLManagerImpl;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
import java.sql.DatabaseMetaData;
|
import java.sql.DatabaseMetaData;
|
||||||
import java.sql.ResultSet;
|
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;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class TableMetadataBuilderImpl
|
public class TableMetadataBuilderImpl
|
||||||
@ -23,12 +30,35 @@ public class TableMetadataBuilderImpl
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Boolean> validateExist() {
|
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
|
@Override
|
||||||
public CompletableFuture<Boolean> isColumnExists(String columnPattern) {
|
public <R> CompletableFuture<R> fetchColumns(@Nullable String columnPattern,
|
||||||
return validate((meta) -> meta.getColumns(null, null, tablePattern, 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
|
* @param supplier supplier to get result set
|
||||||
* @return result future
|
* @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);
|
return getManager().fetchMetadata(supplier, ResultSet::next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.PreparedSQLUpdateBatchAction;
|
||||||
import cc.carm.lib.easysql.api.action.SQLUpdateBatchAction;
|
import cc.carm.lib.easysql.api.action.SQLUpdateBatchAction;
|
||||||
import cc.carm.lib.easysql.api.builder.*;
|
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.SQLDebugHandler;
|
||||||
import cc.carm.lib.easysql.api.function.SQLExceptionHandler;
|
import cc.carm.lib.easysql.api.function.SQLExceptionHandler;
|
||||||
import cc.carm.lib.easysql.api.function.SQLFunction;
|
import cc.carm.lib.easysql.api.function.SQLFunction;
|
||||||
@ -155,10 +156,10 @@ public class SQLManagerImpl implements SQLManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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(() -> {
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
try (Connection conn = getConnection()) {
|
try (Connection conn = getConnection()) {
|
||||||
return metadata.apply(conn.getMetaData());
|
return reader.apply(conn.getMetaData(), conn);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
@ -166,19 +167,16 @@ public class SQLManagerImpl implements SQLManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
@NotNull SQLFunction<@NotNull ResultSet, R> reader) {
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
return fetchMetadata((meta, conn) -> {
|
||||||
try (
|
try (ResultSet rs = supplier.apply(conn.getMetaData(), conn)) {
|
||||||
Connection conn = getConnection();
|
|
||||||
ResultSet rs = supplier.apply(conn.getMetaData())
|
|
||||||
) {
|
|
||||||
if (rs == null) throw new NullPointerException("Metadata返回的ResultSet为null。");
|
if (rs == null) throw new NullPointerException("Metadata返回的ResultSet为null。");
|
||||||
else return reader.apply(rs);
|
else return reader.apply(rs);
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
}, this.executorPool);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user