feat : 模块抽离 + 自定义查分表模块基本完成
This commit is contained in:
66
custom-query/custom-query-submter/pom.xml
Normal file
66
custom-query/custom-query-submter/pom.xml
Normal file
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>custom-query</artifactId>
|
||||
<groupId>cn.fateverse</groupId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>custom-query-submter</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.fateverse</groupId>
|
||||
<artifactId>common-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shardingsphere</groupId>
|
||||
<artifactId>shardingsphere-sql-parser-binder</artifactId>
|
||||
<version>4.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shardingsphere</groupId>
|
||||
<artifactId>shardingsphere-sql-parser-mysql</artifactId>
|
||||
<version>4.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shardingsphere</groupId>
|
||||
<artifactId>shardingsphere-sql-parser-sql92</artifactId>
|
||||
<version>4.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shardingsphere</groupId>
|
||||
<artifactId>shardingsphere-sql-parser-statement</artifactId>
|
||||
<version>4.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shardingsphere</groupId>
|
||||
<artifactId>shardingsphere-merge</artifactId>
|
||||
<version>4.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shardingsphere</groupId>
|
||||
<artifactId>sharding-core-execute</artifactId>
|
||||
<version>4.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shardingsphere</groupId>
|
||||
<artifactId>sharding-jdbc-core</artifactId>
|
||||
<version>4.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,43 @@
|
||||
package cn.fateverse.query.submeter.adapter;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.shardingsphere.shardingjdbc.jdbc.adapter.invocation.JdbcMethodInvocation;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Wrapper;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
public class WrapperAdapter implements Wrapper {
|
||||
|
||||
private final Collection<JdbcMethodInvocation> jdbcMethodInvocations = new ArrayList<>();
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||
if (isWrapperFor(iface)) {
|
||||
return (T) this;
|
||||
}
|
||||
throw new SQLException(String.format("[%s] cannot be unwrapped as [%s]", getClass().getName(), iface.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||
return iface.isInstance(this);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public final void recordMethodInvocation(final Class<?> targetClass, final String methodName, final Class<?>[] argumentTypes, final Object[] arguments) {
|
||||
jdbcMethodInvocations.add(new JdbcMethodInvocation(targetClass.getMethod(methodName, argumentTypes), arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Replay methods invocation.
|
||||
*
|
||||
* @param target target object
|
||||
*/
|
||||
public final void replayMethodsInvocation(final Object target) {
|
||||
for (JdbcMethodInvocation each : jdbcMethodInvocations) {
|
||||
each.invoke(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package cn.fateverse.query.submeter.connection;
|
||||
|
||||
import cn.fateverse.query.submeter.executor.ForceExecuteTemplate;
|
||||
import cn.fateverse.query.submeter.executor.ForceExecuteCallback;
|
||||
import lombok.Getter;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLWarning;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Getter
|
||||
public abstract class AbstractConnectionAdapter extends AbstractUnsupportedOperationConnection{
|
||||
|
||||
|
||||
|
||||
private boolean autoCommit = true;
|
||||
private boolean readOnly = true;
|
||||
private volatile boolean closed;
|
||||
|
||||
|
||||
private int transactionIsolation = TRANSACTION_READ_UNCOMMITTED;
|
||||
|
||||
|
||||
private final List<Connection> cachedConnections = new LinkedList<>();
|
||||
|
||||
private final ForceExecuteTemplate<Connection> forceExecuteTemplate = new ForceExecuteTemplate<>();
|
||||
|
||||
private final ForceExecuteTemplate<Map.Entry<String, Connection>> forceExecuteTemplateForClose = new ForceExecuteTemplate<>();
|
||||
|
||||
public final Connection getConnection() throws SQLException {
|
||||
Connection connection = getDataSource().getConnection();
|
||||
cachedConnections.add(connection);
|
||||
return connection;
|
||||
}
|
||||
|
||||
public final List<Connection> getConnections() throws SQLException {
|
||||
if (cachedConnections.size() > 0){
|
||||
return cachedConnections;
|
||||
}
|
||||
Connection connection = getDataSource().getConnection();
|
||||
cachedConnections.add(connection);
|
||||
return cachedConnections;
|
||||
}
|
||||
|
||||
|
||||
protected abstract DataSource getDataSource();
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void setAutoCommit(boolean autoCommit) throws SQLException {
|
||||
this.autoCommit = autoCommit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAutoCommit() throws SQLException {
|
||||
return autoCommit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commit() throws SQLException {
|
||||
commitForLocalTransaction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rollback() throws SQLException {
|
||||
rollbackForLocalTransaction();
|
||||
}
|
||||
|
||||
private void rollbackForLocalTransaction() throws SQLException {
|
||||
forceExecuteTemplate.execute(cachedConnections, new ForceExecuteCallback<Connection>() {
|
||||
|
||||
@Override
|
||||
public void execute(final Connection connection) throws SQLException {
|
||||
connection.rollback();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void commitForLocalTransaction() throws SQLException {
|
||||
forceExecuteTemplate.execute(cachedConnections, new ForceExecuteCallback<Connection>() {
|
||||
@Override
|
||||
public void execute(final Connection connection) throws SQLException {
|
||||
connection.commit();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws SQLException {
|
||||
closed = true;
|
||||
try {
|
||||
forceExecuteTemplate.execute(cachedConnections , new ForceExecuteCallback<Connection>() {
|
||||
@Override
|
||||
public void execute(final Connection connection) throws SQLException {
|
||||
connection.close();
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
cachedConnections.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed() throws SQLException {
|
||||
return closed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadOnly(boolean readOnly) throws SQLException {
|
||||
this.readOnly = readOnly;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly() throws SQLException {
|
||||
return readOnly;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTransactionIsolation(int level) throws SQLException {
|
||||
transactionIsolation = level;
|
||||
// recordMethodInvocation(Connection.class, "setTransactionIsolation", new Class[]{int.class}, new Object[]{level});
|
||||
forceExecuteTemplate.execute(cachedConnections, connection -> connection.setTransactionIsolation(level));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTransactionIsolation() throws SQLException {
|
||||
if (cachedConnections.isEmpty()) {
|
||||
return transactionIsolation;
|
||||
}
|
||||
return cachedConnections.iterator().next().getTransactionIsolation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLWarning getWarnings() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearWarnings() throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setHoldability(int holdability) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHoldability() throws SQLException {
|
||||
return ResultSet.CLOSE_CURSORS_AT_COMMIT;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
package cn.fateverse.query.submeter.connection;
|
||||
|
||||
import cn.fateverse.query.submeter.adapter.WrapperAdapter;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
public abstract class AbstractUnsupportedOperationConnection extends WrapperAdapter implements Connection {
|
||||
|
||||
@Override
|
||||
public final CallableStatement prepareCall(final String sql) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("prepareCall");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final CallableStatement prepareCall(final String sql, final int resultSetType, final int resultSetConcurrency) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("prepareCall");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final CallableStatement prepareCall(final String sql, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("prepareCall");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String nativeSQL(final String sql) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("nativeSQL");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Savepoint setSavepoint() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("setSavepoint");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Savepoint setSavepoint(final String name) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("setSavepoint name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void releaseSavepoint(final Savepoint savepoint) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("releaseSavepoint");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void rollback(final Savepoint savepoint) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("rollback savepoint");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void abort(final Executor executor) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("abort");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getCatalog() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getCatalog");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setCatalog(final String catalog) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("setCatalog");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getSchema() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getSchema");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSchema(final String schema) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("setSchema");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Map<String, Class<?>> getTypeMap() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getTypeMap");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setTypeMap(final Map<String, Class<?>> map) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("setTypeMap");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getNetworkTimeout() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getNetworkTimeout");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setNetworkTimeout(final Executor executor, final int milliseconds) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("setNetworkTimeout");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clob createClob() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("createClob");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Blob createBlob() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("createBlob");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final NClob createNClob() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("createNClob");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final SQLXML createSQLXML() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("createSQLXML");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Array createArrayOf(final String typeName, final Object[] elements) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("createArrayOf");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Struct createStruct(final String typeName, final Object[] attributes) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("createStruct");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isValid(final int timeout) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("isValid");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Properties getClientInfo() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getClientInfo");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getClientInfo(final String name) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getClientInfo name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setClientInfo(final String name, final String value) {
|
||||
throw new UnsupportedOperationException("setClientInfo name value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setClientInfo(final Properties properties) {
|
||||
throw new UnsupportedOperationException("setClientInfo properties");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package cn.fateverse.query.submeter.connection;
|
||||
|
||||
import cn.fateverse.query.submeter.preparestatement.SubmeterPreparedStatement;
|
||||
import lombok.Getter;
|
||||
import org.apache.shardingsphere.shardingjdbc.jdbc.core.datasource.metadata.CachedDatabaseMetaData;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.*;
|
||||
|
||||
public class SubmeterConnection extends AbstractConnectionAdapter {
|
||||
|
||||
@Getter
|
||||
private final DataSource dataSource;
|
||||
|
||||
private CachedDatabaseMetaData cachedDatabaseMetaData;
|
||||
|
||||
private DatabaseMetaData databaseMetaData;
|
||||
|
||||
public SubmeterConnection(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
databaseMetaData = connection.getMetaData();
|
||||
cachedDatabaseMetaData = new CachedDatabaseMetaData(databaseMetaData);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("出错了");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatabaseMetaData getMetaData() throws SQLException {
|
||||
return databaseMetaData;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Statement createStatement() throws SQLException {
|
||||
// return dataSource.getConnection().createStatement();
|
||||
return new SubmeterPreparedStatement(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql) throws SQLException {
|
||||
return new SubmeterPreparedStatement(this, sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
|
||||
// return dataSource.getConnection().createStatement(resultSetType, resultSetConcurrency);
|
||||
return new SubmeterPreparedStatement(this, resultSetType, resultSetConcurrency);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
|
||||
return new SubmeterPreparedStatement(this, sql, resultSetType, resultSetConcurrency);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
|
||||
return new SubmeterPreparedStatement(this, resultSetType, resultSetConcurrency, resultSetHoldability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
|
||||
return new SubmeterPreparedStatement(this, sql, resultSetType, resultSetConcurrency, resultSetHoldability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
|
||||
return new SubmeterPreparedStatement(this, sql, autoGeneratedKeys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
|
||||
return new SubmeterPreparedStatement(this, sql, Statement.RETURN_GENERATED_KEYS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
|
||||
return new SubmeterPreparedStatement(this, sql, Statement.RETURN_GENERATED_KEYS);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package cn.fateverse.query.submeter.datasource;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public abstract class AbstractDataSourceAdapter extends AbstractUnsupportedOperationDataSource implements AutoCloseable {
|
||||
|
||||
protected final DataSource dataSource;
|
||||
|
||||
|
||||
private PrintWriter logWriter = new PrintWriter(System.out);
|
||||
|
||||
public AbstractDataSourceAdapter(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Logger getParentLogger() {
|
||||
return Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Connection getConnection(final String username, final String password) throws SQLException {
|
||||
return getConnection();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
try {
|
||||
Method method = dataSource.getClass().getDeclaredMethod("close");
|
||||
method.setAccessible(true);
|
||||
method.invoke(dataSource);
|
||||
} catch (final ReflectiveOperationException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrintWriter getLogWriter() throws SQLException {
|
||||
return logWriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogWriter(PrintWriter out) throws SQLException {
|
||||
this.logWriter = out;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package cn.fateverse.query.submeter.datasource;
|
||||
|
||||
import cn.fateverse.query.submeter.adapter.WrapperAdapter;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLFeatureNotSupportedException;
|
||||
|
||||
public abstract class AbstractUnsupportedOperationDataSource extends WrapperAdapter implements DataSource {
|
||||
|
||||
@Override
|
||||
public final int getLoginTimeout() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("unsupported getLoginTimeout()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setLoginTimeout(final int seconds) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("unsupported setLoginTimeout(int seconds)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.fateverse.query.submeter.datasource;
|
||||
|
||||
|
||||
import cn.fateverse.query.submeter.connection.SubmeterConnection;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
public class SubmeterDataSource extends AbstractDataSourceAdapter {
|
||||
|
||||
|
||||
|
||||
public SubmeterDataSource(DataSource dataSource) {
|
||||
super(dataSource);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final SubmeterConnection getConnection() {
|
||||
return new SubmeterConnection(dataSource);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package cn.fateverse.query.submeter.datasource;
|
||||
|
||||
public class SubmeterDataSourceFactory {
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package cn.fateverse.query.submeter.executor;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
public interface ForceExecuteCallback<T> {
|
||||
|
||||
/**
|
||||
* Execute.
|
||||
*
|
||||
* @param target target to be executed
|
||||
* @throws SQLException SQL exception
|
||||
*/
|
||||
void execute(T target) throws SQLException;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package cn.fateverse.query.submeter.executor;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class ForceExecuteTemplate <T> {
|
||||
|
||||
/**
|
||||
* Force execute.
|
||||
*
|
||||
* @param targets targets to be executed
|
||||
* @param callback force execute callback
|
||||
* @throws SQLException throw SQL exception after all targets are executed
|
||||
*/
|
||||
public void execute(final Collection<T> targets, final ForceExecuteCallback<T> callback) throws SQLException {
|
||||
Collection<SQLException> exceptions = new LinkedList<>();
|
||||
for (T each : targets) {
|
||||
try {
|
||||
callback.execute(each);
|
||||
} catch (final SQLException ex) {
|
||||
exceptions.add(ex);
|
||||
}
|
||||
}
|
||||
throwSQLExceptionIfNecessary(exceptions);
|
||||
}
|
||||
|
||||
private void throwSQLExceptionIfNecessary(final Collection<SQLException> exceptions) throws SQLException {
|
||||
if (exceptions.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
SQLException ex = new SQLException();
|
||||
for (SQLException each : exceptions) {
|
||||
ex.setNextException(each);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.fateverse.query.submeter.invocation;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class JdbcMethodInvocation {
|
||||
|
||||
@Getter
|
||||
private final Method method;
|
||||
|
||||
@Getter
|
||||
private final Object[] arguments;
|
||||
|
||||
/**
|
||||
* Invoke JDBC method.
|
||||
*
|
||||
* @param target target object
|
||||
*/
|
||||
@SneakyThrows
|
||||
public void invoke(final Object target) {
|
||||
method.invoke(target, arguments);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package cn.fateverse.query.submeter.invocation;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public final class SetParameterMethodInvocation extends JdbcMethodInvocation {
|
||||
|
||||
@Getter
|
||||
private final int index;
|
||||
|
||||
@Getter
|
||||
private final Object value;
|
||||
|
||||
public SetParameterMethodInvocation(final Method method, final Object[] arguments, final Object value) {
|
||||
super(method, arguments);
|
||||
this.index = (int) arguments[0];
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set argument.
|
||||
*
|
||||
* @param value argument value
|
||||
*/
|
||||
public void changeValueArgument(final Object value) {
|
||||
getArguments()[1] = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
package cn.fateverse.query.submeter.preparestatement;
|
||||
|
||||
import cn.fateverse.query.submeter.executor.ForceExecuteCallback;
|
||||
import cn.fateverse.query.submeter.executor.ForceExecuteTemplate;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLWarning;
|
||||
import java.sql.Statement;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public abstract class AbstractStatementAdapter extends AbstractUnsupportedOperationStatement {
|
||||
|
||||
private final Class<? extends Statement> targetClass;
|
||||
|
||||
private boolean closed;
|
||||
|
||||
private boolean poolable;
|
||||
|
||||
private int fetchSize;
|
||||
|
||||
private final ForceExecuteTemplate<Statement> forceExecuteTemplate = new ForceExecuteTemplate<>();
|
||||
|
||||
|
||||
@Getter
|
||||
private final List<Statement> statements = new LinkedList<>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final void close() throws SQLException {
|
||||
closed = true;
|
||||
try {
|
||||
forceExecuteTemplate.execute(statements, new ForceExecuteCallback<Statement>() {
|
||||
|
||||
@Override
|
||||
public void execute(final Statement statement) throws SQLException {
|
||||
statement.close();
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
statements.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isPoolable() {
|
||||
return poolable;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final void setPoolable(final boolean poolable) throws SQLException {
|
||||
this.poolable = poolable;
|
||||
forceExecuteTemplate.execute(statements, new ForceExecuteCallback<Statement>() {
|
||||
|
||||
@Override
|
||||
public void execute(final Statement statement) throws SQLException {
|
||||
statement.setPoolable(poolable);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getFetchSize() {
|
||||
return fetchSize;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final void setFetchSize(final int rows) throws SQLException {
|
||||
this.fetchSize = rows;
|
||||
// statements.forEach(statement -> {
|
||||
// try {
|
||||
// statement.setFetchSize(rows);
|
||||
// } catch (SQLException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
// });
|
||||
// recordMethodInvocation(targetClass, "setFetchSize", new Class[] {int.class}, new Object[] {rows});
|
||||
forceExecuteTemplate.execute(statements, new ForceExecuteCallback<Statement>() {
|
||||
|
||||
@Override
|
||||
public void execute(final Statement statement) throws SQLException {
|
||||
statement.setFetchSize(rows);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final void setEscapeProcessing(final boolean enable) throws SQLException {
|
||||
forceExecuteTemplate.execute(statements, new ForceExecuteCallback<Statement>() {
|
||||
|
||||
@Override
|
||||
public void execute(final Statement statement) throws SQLException {
|
||||
statement.setEscapeProcessing(enable);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final void cancel() throws SQLException {
|
||||
forceExecuteTemplate.execute(statements, new ForceExecuteCallback<Statement>() {
|
||||
|
||||
@Override
|
||||
public void execute(final Statement statement) throws SQLException {
|
||||
statement.cancel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getUpdateCount() throws SQLException {
|
||||
if (isAccumulate()) {
|
||||
return accumulate();
|
||||
} else {
|
||||
Collection<? extends Statement> statements = this.statements;
|
||||
if (0 == statements.size()) {
|
||||
return -1;
|
||||
}
|
||||
return this.statements.iterator().next().getUpdateCount();
|
||||
}
|
||||
}
|
||||
|
||||
private int accumulate() throws SQLException {
|
||||
long result = 0;
|
||||
boolean hasResult = false;
|
||||
for (Statement each : this.statements) {
|
||||
int updateCount = each.getUpdateCount();
|
||||
if (updateCount > -1) {
|
||||
hasResult = true;
|
||||
}
|
||||
result += updateCount;
|
||||
}
|
||||
if (result > Integer.MAX_VALUE) {
|
||||
result = Integer.MAX_VALUE;
|
||||
}
|
||||
return hasResult ? Long.valueOf(result).intValue() : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final SQLWarning getWarnings() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void clearWarnings() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean getMoreResults() throws SQLException {
|
||||
boolean result = false;
|
||||
for (Statement each : this.statements) {
|
||||
result = each.getMoreResults();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean getMoreResults(final int current) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getMaxFieldSize() throws SQLException {
|
||||
return this.statements.isEmpty() ? 0 : this.statements.iterator().next().getMaxFieldSize();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final void setMaxFieldSize(final int max) throws SQLException {
|
||||
// recordMethodInvocation(targetClass, "setMaxFieldSize", new Class[] {int.class}, new Object[] {max});
|
||||
forceExecuteTemplate.execute(this.statements, new ForceExecuteCallback<Statement>() {
|
||||
|
||||
@Override
|
||||
public void execute(final Statement statement) throws SQLException {
|
||||
statement.setMaxFieldSize(max);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// TODO Confirm MaxRows for multiple databases is need special handle. eg: 10 statements maybe MaxRows / 10
|
||||
@Override
|
||||
public final int getMaxRows() throws SQLException {
|
||||
return this.statements.isEmpty() ? -1 : this.statements.iterator().next().getMaxRows();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final void setMaxRows(final int max) throws SQLException {
|
||||
// recordMethodInvocation(targetClass, "setMaxRows", new Class[] {int.class}, new Object[] {max});
|
||||
forceExecuteTemplate.execute(this.statements, new ForceExecuteCallback<Statement>() {
|
||||
|
||||
@Override
|
||||
public void execute(final Statement statement) throws SQLException {
|
||||
statement.setMaxRows(max);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getQueryTimeout() throws SQLException {
|
||||
return this.statements.isEmpty() ? 0 : this.statements.iterator().next().getQueryTimeout();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final void setQueryTimeout(final int seconds) throws SQLException {
|
||||
|
||||
// recordMethodInvocation(targetClass, "setQueryTimeout", new Class[] {int.class}, new Object[] {seconds});
|
||||
forceExecuteTemplate.execute(this.statements, new ForceExecuteCallback<Statement>() {
|
||||
|
||||
@Override
|
||||
public void execute(final Statement statement) throws SQLException {
|
||||
statement.setQueryTimeout(seconds);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract boolean isAccumulate();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,256 @@
|
||||
package cn.fateverse.query.submeter.preparestatement;
|
||||
|
||||
import cn.fateverse.query.submeter.invocation.SetParameterMethodInvocation;
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URL;
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractSubmeterPreparedStatementAdapter extends AbstractUnsupportedOperationPreparedStatement {
|
||||
|
||||
private final List<SetParameterMethodInvocation> setParameterMethodInvocations = new LinkedList<>();
|
||||
|
||||
@Getter
|
||||
private final List<Object> parameters = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public final void setNull(final int parameterIndex, final int sqlType) {
|
||||
setParameter(parameterIndex, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setNull(final int parameterIndex, final int sqlType, final String typeName) {
|
||||
setParameter(parameterIndex, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setBoolean(final int parameterIndex, final boolean x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setByte(final int parameterIndex, final byte x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setShort(final int parameterIndex, final short x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setInt(final int parameterIndex, final int x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setLong(final int parameterIndex, final long x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setFloat(final int parameterIndex, final float x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setDouble(final int parameterIndex, final double x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setString(final int parameterIndex, final String x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setBigDecimal(final int parameterIndex, final BigDecimal x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setDate(final int parameterIndex, final Date x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setDate(final int parameterIndex, final Date x, final Calendar cal) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setTime(final int parameterIndex, final Time x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setTime(final int parameterIndex, final Time x, final Calendar cal) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setTimestamp(final int parameterIndex, final Timestamp x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setTimestamp(final int parameterIndex, final Timestamp x, final Calendar cal) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setBytes(final int parameterIndex, final byte[] x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setBlob(final int parameterIndex, final Blob x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setBlob(final int parameterIndex, final InputStream x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setBlob(final int parameterIndex, final InputStream x, final long length) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setClob(final int parameterIndex, final Clob x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setClob(final int parameterIndex, final Reader x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setClob(final int parameterIndex, final Reader x, final long length) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setAsciiStream(final int parameterIndex, final InputStream x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setAsciiStream(final int parameterIndex, final InputStream x, final int length) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setAsciiStream(final int parameterIndex, final InputStream x, final long length) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public final void setUnicodeStream(final int parameterIndex, final InputStream x, final int length) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setBinaryStream(final int parameterIndex, final InputStream x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setBinaryStream(final int parameterIndex, final InputStream x, final int length) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setBinaryStream(final int parameterIndex, final InputStream x, final long length) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setCharacterStream(final int parameterIndex, final Reader x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setCharacterStream(final int parameterIndex, final Reader x, final int length) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setCharacterStream(final int parameterIndex, final Reader x, final long length) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setURL(final int parameterIndex, final URL x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSQLXML(final int parameterIndex, final SQLXML x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setObject(final int parameterIndex, final Object x) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setObject(final int parameterIndex, final Object x, final int targetSqlType) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setObject(final int parameterIndex, final Object x, final int targetSqlType, final int scaleOrLength) {
|
||||
setParameter(parameterIndex, x);
|
||||
}
|
||||
|
||||
private void setParameter(final int parameterIndex, final Object value) {
|
||||
if (parameters.size() == parameterIndex - 1) {
|
||||
parameters.add(value);
|
||||
return;
|
||||
}
|
||||
for (int i = parameters.size(); i <= parameterIndex - 1; i++) {
|
||||
parameters.add(null);
|
||||
}
|
||||
parameters.set(parameterIndex - 1, value);
|
||||
}
|
||||
|
||||
protected final void replaySetParameter(final PreparedStatement preparedStatement, final List<Object> parameters) {
|
||||
setParameterMethodInvocations.clear();
|
||||
addParameters(parameters);
|
||||
for (SetParameterMethodInvocation each : setParameterMethodInvocations) {
|
||||
each.invoke(preparedStatement);
|
||||
}
|
||||
}
|
||||
|
||||
private void addParameters(final List<Object> parameters) {
|
||||
int i = 0;
|
||||
for (Object each : parameters) {
|
||||
setParameter(new Class[]{int.class, Object.class}, i++ + 1, each);
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void setParameter(final Class[] argumentTypes, final Object... arguments) {
|
||||
setParameterMethodInvocations.add(new SetParameterMethodInvocation(PreparedStatement.class.getMethod("setObject", argumentTypes), arguments, arguments[1]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void clearParameters() {
|
||||
parameters.clear();
|
||||
setParameterMethodInvocations.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package cn.fateverse.query.submeter.preparestatement;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.sql.*;
|
||||
|
||||
public abstract class AbstractUnsupportedOperationPreparedStatement extends AbstractStatementAdapter implements PreparedStatement {
|
||||
|
||||
|
||||
public AbstractUnsupportedOperationPreparedStatement() {
|
||||
super(PreparedStatement.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ResultSetMetaData getMetaData() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getMetaData");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ParameterMetaData getParameterMetaData() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("ParameterMetaData");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setNString(final int parameterIndex, final String x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("setNString");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setNClob(final int parameterIndex, final NClob x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("setNClob");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setNClob(final int parameterIndex, final Reader x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("setNClob");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setNClob(final int parameterIndex, final Reader x, final long length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("setNClob");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setNCharacterStream(final int parameterIndex, final Reader x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("setNCharacterStream");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setNCharacterStream(final int parameterIndex, final Reader x, final long length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("setNCharacterStream");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setArray(final int parameterIndex, final Array x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("setArray");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setRowId(final int parameterIndex, final RowId x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("setRowId");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setRef(final int parameterIndex, final Ref x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("setRef");
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public final ResultSet executeQuery(final String sql) throws SQLException {
|
||||
// throw new SQLFeatureNotSupportedException("executeQuery with SQL for PreparedStatement");
|
||||
// }
|
||||
|
||||
@Override
|
||||
public final int executeUpdate(final String sql) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("executeUpdate with SQL for PreparedStatement");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int executeUpdate(final String sql, final int autoGeneratedKeys) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("executeUpdate with SQL for PreparedStatement");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int executeUpdate(final String sql, final int[] columnIndexes) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("executeUpdate with SQL for PreparedStatement");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int executeUpdate(final String sql, final String[] columnNames) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("executeUpdate with SQL for PreparedStatement");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean execute(final String sql) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("execute with SQL for PreparedStatement");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean execute(final String sql, final int autoGeneratedKeys) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("execute with SQL for PreparedStatement");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean execute(final String sql, final int[] columnIndexes) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("execute with SQL for PreparedStatement");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean execute(final String sql, final String[] columnNames) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("execute with SQL for PreparedStatement");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package cn.fateverse.query.submeter.preparestatement;
|
||||
|
||||
import cn.fateverse.query.submeter.adapter.WrapperAdapter;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.sql.Statement;
|
||||
|
||||
public abstract class AbstractUnsupportedOperationStatement extends WrapperAdapter implements Statement {
|
||||
|
||||
@Override
|
||||
public final int getFetchDirection() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getFetchDirection");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setFetchDirection(final int direction) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("setFetchDirection");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void addBatch(final String sql) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("addBatch sql");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearBatch() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("clearBatch");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] executeBatch() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("executeBatch");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void closeOnCompletion() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("closeOnCompletion");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isCloseOnCompletion() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("isCloseOnCompletion");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setCursorName(final String name) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("setCursorName");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
package cn.fateverse.query.submeter.preparestatement;
|
||||
|
||||
import cn.fateverse.query.submeter.connection.SubmeterConnection;
|
||||
import cn.fateverse.query.submeter.executor.ForceExecuteTemplate;
|
||||
import cn.fateverse.query.submeter.result.SubmeterResult;
|
||||
import org.apache.shardingsphere.sharding.execute.sql.execute.result.StreamQueryResult;
|
||||
import org.apache.shardingsphere.sharding.merge.dql.ShardingDQLResultMerger;
|
||||
import org.apache.shardingsphere.sql.parser.SQLParserEngine;
|
||||
import org.apache.shardingsphere.sql.parser.SQLParserEngineFactory;
|
||||
import org.apache.shardingsphere.sql.parser.binder.SQLStatementContextFactory;
|
||||
import org.apache.shardingsphere.sql.parser.binder.metadata.schema.SchemaMetaData;
|
||||
import org.apache.shardingsphere.sql.parser.binder.metadata.table.TableMetaData;
|
||||
import org.apache.shardingsphere.sql.parser.binder.metadata.table.TableMetaDataLoader;
|
||||
import org.apache.shardingsphere.sql.parser.binder.statement.SQLStatementContext;
|
||||
import org.apache.shardingsphere.sql.parser.sql.statement.SQLStatement;
|
||||
import org.apache.shardingsphere.underlying.common.database.type.dialect.MySQLDatabaseType;
|
||||
import org.apache.shardingsphere.underlying.executor.QueryResult;
|
||||
import org.apache.shardingsphere.underlying.merge.result.MergedResult;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SubmeterPreparedStatement extends AbstractSubmeterPreparedStatementAdapter {
|
||||
|
||||
private final SubmeterConnection connection;
|
||||
|
||||
private final String sql;
|
||||
private final int resultSetType;
|
||||
private final int resultSetConcurrency;
|
||||
private final int resultSetHoldability;
|
||||
private final boolean returnGeneratedKeys;
|
||||
|
||||
private final SQLParserEngine parserEngine;
|
||||
|
||||
private ResultSet currentResultSet;
|
||||
|
||||
|
||||
private final ForceExecuteTemplate<Statement> forceExecuteTemplate = new ForceExecuteTemplate<>();
|
||||
|
||||
|
||||
public SubmeterPreparedStatement(final SubmeterConnection connection) {
|
||||
this(connection, "", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT, false);
|
||||
}
|
||||
|
||||
public SubmeterPreparedStatement(final SubmeterConnection connection, final String sql) {
|
||||
this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT, false);
|
||||
}
|
||||
|
||||
public SubmeterPreparedStatement(final SubmeterConnection connection, final String sql, final int resultSetType, final int resultSetConcurrency) {
|
||||
this(connection, sql, resultSetType, resultSetConcurrency, ResultSet.HOLD_CURSORS_OVER_COMMIT, false);
|
||||
}
|
||||
|
||||
|
||||
public SubmeterPreparedStatement(final SubmeterConnection connection, final String sql, final int autoGeneratedKeys) {
|
||||
this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT, Statement.RETURN_GENERATED_KEYS == autoGeneratedKeys);
|
||||
}
|
||||
|
||||
public SubmeterPreparedStatement(final SubmeterConnection connection, final String sql, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) {
|
||||
this(connection, sql, resultSetType, resultSetConcurrency, resultSetHoldability, false);
|
||||
}
|
||||
|
||||
public SubmeterPreparedStatement(final SubmeterConnection connection, final int resultSetType, final int resultSetConcurrency) {
|
||||
this(connection, "", resultSetType, resultSetConcurrency, ResultSet.HOLD_CURSORS_OVER_COMMIT, false);
|
||||
}
|
||||
|
||||
|
||||
public SubmeterPreparedStatement(final SubmeterConnection connection, final int autoGeneratedKeys) {
|
||||
this(connection, "", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT, Statement.RETURN_GENERATED_KEYS == autoGeneratedKeys);
|
||||
}
|
||||
|
||||
public SubmeterPreparedStatement(final SubmeterConnection connection, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) {
|
||||
this(connection, "", resultSetType, resultSetConcurrency, resultSetHoldability, false);
|
||||
}
|
||||
|
||||
|
||||
private SubmeterPreparedStatement(
|
||||
final SubmeterConnection connection, final String sql, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability, final boolean returnGeneratedKeys) {
|
||||
this.connection = connection;
|
||||
this.sql = sql;
|
||||
this.resultSetConcurrency = resultSetConcurrency;
|
||||
this.resultSetType = resultSetType;
|
||||
this.resultSetHoldability = resultSetHoldability;
|
||||
this.returnGeneratedKeys = returnGeneratedKeys;
|
||||
this.parserEngine = SQLParserEngineFactory.getSQLParserEngine("MySQL");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAccumulate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ResultSet executeQuery() throws SQLException {
|
||||
return getStatements().get(0)
|
||||
.executeQuery(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet executeQuery(String sql) throws SQLException {
|
||||
return getStatements().get(0)
|
||||
.executeQuery(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute() throws SQLException {
|
||||
Connection connection1 = connection.getConnection();
|
||||
|
||||
PreparedStatement preparedStatement1 = connection1.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
|
||||
getStatements().add(preparedStatement1);
|
||||
|
||||
PreparedStatement preparedStatement2 = connection1.prepareStatement(sql.replace("sys_operation_log_1", "sys_operation_log_2"), resultSetType, resultSetConcurrency, resultSetHoldability);
|
||||
getStatements().add(preparedStatement2);
|
||||
List<Boolean> booleans = new ArrayList<>(getStatements().size());
|
||||
|
||||
|
||||
|
||||
setParametersForStatements();
|
||||
replayMethodForStatements();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
forceExecuteTemplate.execute(getStatements(), (statement) -> {
|
||||
boolean execute = ((PreparedStatement) statement).execute();
|
||||
booleans.add(execute);
|
||||
});
|
||||
|
||||
|
||||
SQLStatement sqlStatement = parserEngine.parse(sql, false);
|
||||
Map<String, TableMetaData> tableMetaDataMap = new HashMap<>(1, 1);
|
||||
|
||||
TableMetaData metaData1 = TableMetaDataLoader.load(connection.getDataSource(), "sys_operation_log_1", "MySQL");
|
||||
tableMetaDataMap.put("sys_operation_log_1", metaData1);
|
||||
TableMetaData metaData2 = TableMetaDataLoader.load(connection.getDataSource(), "sys_operation_log_2", "MySQL");
|
||||
tableMetaDataMap.put("sys_operation_log_2", metaData2);
|
||||
SchemaMetaData schemaMetaData = new SchemaMetaData(tableMetaDataMap);
|
||||
|
||||
SQLStatementContext sqlStatementContext = SQLStatementContextFactory.newInstance(schemaMetaData, sql, getParameters(), sqlStatement);
|
||||
MySQLDatabaseType databaseType = new MySQLDatabaseType();
|
||||
ShardingDQLResultMerger shardingDQLResultMerger = new ShardingDQLResultMerger(databaseType);
|
||||
|
||||
|
||||
List<ResultSet> resultSets = getResultSets();
|
||||
List<QueryResult> queryResults = getQueryResults(resultSets);
|
||||
MergedResult mergedResult = shardingDQLResultMerger.merge(queryResults, sqlStatementContext, schemaMetaData);
|
||||
SubmeterResult result = new SubmeterResult(resultSets, mergedResult, sqlStatementContext, this);
|
||||
|
||||
|
||||
currentResultSet = result;
|
||||
|
||||
return booleans.get(0);
|
||||
}
|
||||
|
||||
|
||||
private void setParametersForStatements() {
|
||||
for (int i = 0; i < getStatements().size(); i++) {
|
||||
replaySetParameter((PreparedStatement) getStatements().get(i), getParameters());
|
||||
}
|
||||
}
|
||||
private void replayMethodForStatements() {
|
||||
for (Statement each : getStatements()) {
|
||||
replayMethodsInvocation(each);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearPrevious() throws SQLException {
|
||||
getStatements().clear();
|
||||
getParameters().clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBatch() throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getResultSet() throws SQLException {
|
||||
if (null != currentResultSet) {
|
||||
return currentResultSet;
|
||||
}
|
||||
if (getStatements().size() > 0) {
|
||||
|
||||
|
||||
return getStatements().get(0).getResultSet();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private List<ResultSet> getResultSets() throws SQLException {
|
||||
List<ResultSet> result = new ArrayList<>(getStatements().size());
|
||||
for (Statement each : getStatements()) {
|
||||
result.add(each.getResultSet());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private List<QueryResult> getQueryResults(final List<ResultSet> resultSets) throws SQLException {
|
||||
List<QueryResult> result = new ArrayList<>(resultSets.size());
|
||||
for (ResultSet each : resultSets) {
|
||||
if (null != each) {
|
||||
result.add(new StreamQueryResult(each));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResultSetConcurrency() throws SQLException {
|
||||
return resultSetConcurrency;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResultSetType() throws SQLException {
|
||||
return resultSetType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
return connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getGeneratedKeys() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResultSetHoldability() throws SQLException {
|
||||
return resultSetHoldability;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package cn.fateverse.query.submeter.result;
|
||||
|
||||
import cn.fateverse.query.submeter.executor.ForceExecuteTemplate;
|
||||
import cn.fateverse.query.submeter.unsupported.AbstractUnsupportedOperationResultSet;
|
||||
import lombok.Getter;
|
||||
import org.apache.shardingsphere.sql.parser.binder.statement.SQLStatementContext;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLWarning;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2024/4/7 16:59
|
||||
*/
|
||||
public abstract class AbstractResultSetAdapter extends AbstractUnsupportedOperationResultSet {
|
||||
|
||||
@Getter
|
||||
private final List<ResultSet> resultSets;
|
||||
|
||||
@Getter
|
||||
private final SQLStatementContext sqlStatementContext;
|
||||
|
||||
private boolean closed;
|
||||
|
||||
private final ForceExecuteTemplate<ResultSet> forceExecuteTemplate = new ForceExecuteTemplate<>();
|
||||
|
||||
|
||||
protected AbstractResultSetAdapter(List<ResultSet> resultSets, SQLStatementContext sqlStatementContext) {
|
||||
this.resultSets = resultSets;
|
||||
this.sqlStatementContext = sqlStatementContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ResultSetMetaData getMetaData() throws SQLException {
|
||||
return new SubmeterResultSetMetaData(resultSets.get(0).getMetaData(), sqlStatementContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int findColumn(final String columnLabel) throws SQLException {
|
||||
return resultSets.get(0).findColumn(columnLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void close() throws SQLException {
|
||||
closed = true;
|
||||
forceExecuteTemplate.execute(resultSets, ResultSet::close);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setFetchDirection(final int direction) throws SQLException {
|
||||
forceExecuteTemplate.execute(resultSets, resultSet -> resultSet.setFetchDirection(direction));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getFetchDirection() throws SQLException {
|
||||
return resultSets.get(0).getFetchDirection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setFetchSize(final int rows) throws SQLException {
|
||||
forceExecuteTemplate.execute(resultSets, resultSet -> resultSet.setFetchSize(rows));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getFetchSize() throws SQLException {
|
||||
return resultSets.get(0).getFetchSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getType() throws SQLException {
|
||||
return resultSets.get(0).getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getConcurrency() throws SQLException {
|
||||
return resultSets.get(0).getConcurrency();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final SQLWarning getWarnings() throws SQLException {
|
||||
return resultSets.get(0).getWarnings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void clearWarnings() throws SQLException {
|
||||
forceExecuteTemplate.execute(resultSets, ResultSet::clearWarnings);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,350 @@
|
||||
package cn.fateverse.query.submeter.result;
|
||||
|
||||
import cn.fateverse.query.submeter.util.ResultSetUtil;
|
||||
import org.apache.shardingsphere.sql.parser.binder.statement.SQLStatementContext;
|
||||
import org.apache.shardingsphere.underlying.merge.result.MergedResult;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URL;
|
||||
import java.sql.*;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2024/4/7 17:07
|
||||
*/
|
||||
public class SubmeterResult extends AbstractResultSetAdapter {
|
||||
|
||||
|
||||
private final MergedResult mergeResultSet;
|
||||
|
||||
private final Statement statement;
|
||||
|
||||
private final Map<String, Integer> columnLabelAndIndexMap;
|
||||
|
||||
public SubmeterResult(final List<ResultSet> resultSets, final MergedResult mergeResultSet, SQLStatementContext sqlStatementContext, Statement statement) throws SQLException {
|
||||
super(resultSets, sqlStatementContext);
|
||||
this.mergeResultSet = mergeResultSet;
|
||||
columnLabelAndIndexMap = createColumnLabelAndIndexMap(resultSets.get(0).getMetaData());
|
||||
this.statement = statement;
|
||||
}
|
||||
|
||||
private Map<String, Integer> createColumnLabelAndIndexMap(final ResultSetMetaData resultSetMetaData) throws SQLException {
|
||||
Map<String, Integer> result = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
for (int columnIndex = resultSetMetaData.getColumnCount(); columnIndex > 0; columnIndex--) {
|
||||
result.put(resultSetMetaData.getColumnLabel(columnIndex), columnIndex);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean next() throws SQLException {
|
||||
return mergeResultSet.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasNull() throws SQLException {
|
||||
return mergeResultSet.wasNull();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(final int columnIndex) throws SQLException {
|
||||
return (boolean) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, boolean.class), boolean.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (boolean) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, boolean.class), boolean.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getByte(final int columnIndex) throws SQLException {
|
||||
return (byte) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, byte.class), byte.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getByte(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (byte) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, byte.class), byte.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getShort(final int columnIndex) throws SQLException {
|
||||
return (short) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, short.class), short.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getShort(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (short) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, short.class), short.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(final int columnIndex) throws SQLException {
|
||||
return (int) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, int.class), int.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (int) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, int.class), int.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(final int columnIndex) throws SQLException {
|
||||
return (long) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, long.class), long.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (long) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, long.class), long.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFloat(final int columnIndex) throws SQLException {
|
||||
return (float) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, float.class), float.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFloat(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (float) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, float.class), float.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(final int columnIndex) throws SQLException {
|
||||
return (double) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, double.class), double.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (double) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, double.class), double.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(final int columnIndex) throws SQLException {
|
||||
return (String) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, String.class), String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (String) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, String.class), String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getBigDecimal(final int columnIndex) throws SQLException {
|
||||
return (BigDecimal) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, BigDecimal.class), BigDecimal.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getBigDecimal(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (BigDecimal) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, BigDecimal.class), BigDecimal.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement getStatement() throws SQLException {
|
||||
return statement;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public BigDecimal getBigDecimal(final int columnIndex, final int scale) throws SQLException {
|
||||
return (BigDecimal) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, BigDecimal.class), BigDecimal.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public BigDecimal getBigDecimal(final String columnLabel, final int scale) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (BigDecimal) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, BigDecimal.class), BigDecimal.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes(final int columnIndex) throws SQLException {
|
||||
return (byte[]) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, byte[].class), byte[].class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (byte[]) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, byte[].class), byte[].class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getDate(final int columnIndex) throws SQLException {
|
||||
return (Date) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, Date.class), Date.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getDate(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (Date) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, Date.class), Date.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getDate(final int columnIndex, final Calendar cal) throws SQLException {
|
||||
return (Date) ResultSetUtil.convertValue(mergeResultSet.getCalendarValue(columnIndex, Date.class, cal), Date.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getDate(final String columnLabel, final Calendar cal) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (Date) ResultSetUtil.convertValue(mergeResultSet.getCalendarValue(columnIndex, Date.class, cal), Date.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Time getTime(final int columnIndex) throws SQLException {
|
||||
return (Time) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, Time.class), Time.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Time getTime(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (Time) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, Time.class), Time.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Time getTime(final int columnIndex, final Calendar cal) throws SQLException {
|
||||
return (Time) ResultSetUtil.convertValue(mergeResultSet.getCalendarValue(columnIndex, Time.class, cal), Time.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Time getTime(final String columnLabel, final Calendar cal) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (Time) ResultSetUtil.convertValue(mergeResultSet.getCalendarValue(columnIndex, Time.class, cal), Time.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp getTimestamp(final int columnIndex) throws SQLException {
|
||||
return (Timestamp) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, Timestamp.class), Timestamp.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp getTimestamp(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (Timestamp) ResultSetUtil.convertValue(mergeResultSet.getValue(columnIndex, Timestamp.class), Timestamp.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp getTimestamp(final int columnIndex, final Calendar cal) throws SQLException {
|
||||
return (Timestamp) ResultSetUtil.convertValue(mergeResultSet.getCalendarValue(columnIndex, Timestamp.class, cal), Timestamp.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamp getTimestamp(final String columnLabel, final Calendar cal) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (Timestamp) ResultSetUtil.convertValue(mergeResultSet.getCalendarValue(columnIndex, Timestamp.class, cal), Timestamp.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getAsciiStream(final int columnIndex) throws SQLException {
|
||||
return mergeResultSet.getInputStream(columnIndex, "Ascii");
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getAsciiStream(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return mergeResultSet.getInputStream(columnIndex, "Ascii");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public InputStream getUnicodeStream(final int columnIndex) throws SQLException {
|
||||
return mergeResultSet.getInputStream(columnIndex, "Unicode");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public InputStream getUnicodeStream(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return mergeResultSet.getInputStream(columnIndex, "Unicode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBinaryStream(final int columnIndex) throws SQLException {
|
||||
return mergeResultSet.getInputStream(columnIndex, "Binary");
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBinaryStream(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return mergeResultSet.getInputStream(columnIndex, "Binary");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reader getCharacterStream(final int columnIndex) throws SQLException {
|
||||
return (Reader) mergeResultSet.getValue(columnIndex, Reader.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reader getCharacterStream(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (Reader) mergeResultSet.getValue(columnIndex, Reader.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blob getBlob(final int columnIndex) throws SQLException {
|
||||
return (Blob) mergeResultSet.getValue(columnIndex, Blob.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blob getBlob(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (Blob) mergeResultSet.getValue(columnIndex, Blob.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clob getClob(final int columnIndex) throws SQLException {
|
||||
return (Clob) mergeResultSet.getValue(columnIndex, Clob.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clob getClob(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (Clob) mergeResultSet.getValue(columnIndex, Clob.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getURL(final int columnIndex) throws SQLException {
|
||||
return (URL) mergeResultSet.getValue(columnIndex, URL.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getURL(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (URL) mergeResultSet.getValue(columnIndex, URL.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLXML getSQLXML(final int columnIndex) throws SQLException {
|
||||
return (SQLXML) mergeResultSet.getValue(columnIndex, SQLXML.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLXML getSQLXML(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return (SQLXML) mergeResultSet.getValue(columnIndex, SQLXML.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject(final int columnIndex) throws SQLException {
|
||||
return mergeResultSet.getValue(columnIndex, Object.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject(final String columnLabel) throws SQLException {
|
||||
int columnIndex = columnLabelAndIndexMap.get(columnLabel);
|
||||
return mergeResultSet.getValue(columnIndex, Object.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package cn.fateverse.query.submeter.result;
|
||||
|
||||
import cn.fateverse.query.submeter.adapter.WrapperAdapter;
|
||||
import org.apache.shardingsphere.sql.parser.binder.segment.select.projection.Projection;
|
||||
import org.apache.shardingsphere.sql.parser.binder.segment.select.projection.impl.ColumnProjection;
|
||||
import org.apache.shardingsphere.sql.parser.binder.statement.SQLStatementContext;
|
||||
import org.apache.shardingsphere.sql.parser.binder.statement.dml.SelectStatementContext;
|
||||
import org.apache.shardingsphere.underlying.common.database.DefaultSchema;
|
||||
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2024/4/8 14:04
|
||||
*/
|
||||
public class SubmeterResultSetMetaData extends WrapperAdapter implements ResultSetMetaData {
|
||||
|
||||
private final ResultSetMetaData resultSetMetaData;
|
||||
|
||||
private final SQLStatementContext sqlStatementContext;
|
||||
|
||||
public SubmeterResultSetMetaData(ResultSetMetaData resultSetMetaData, SQLStatementContext sqlStatementContext) {
|
||||
this.resultSetMetaData = resultSetMetaData;
|
||||
this.sqlStatementContext = sqlStatementContext;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getColumnCount() throws SQLException {
|
||||
return sqlStatementContext instanceof SelectStatementContext ? ((SelectStatementContext) sqlStatementContext).getProjectionsContext().getExpandProjections().size() : 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isAutoIncrement(final int column) throws SQLException {
|
||||
return resultSetMetaData.isAutoIncrement(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCaseSensitive(final int column) throws SQLException {
|
||||
return resultSetMetaData.isCaseSensitive(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSearchable(final int column) throws SQLException {
|
||||
return resultSetMetaData.isSearchable(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrency(final int column) throws SQLException {
|
||||
return resultSetMetaData.isCurrency(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int isNullable(final int column) throws SQLException {
|
||||
return resultSetMetaData.isNullable(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSigned(final int column) throws SQLException {
|
||||
return resultSetMetaData.isSigned(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnDisplaySize(final int column) throws SQLException {
|
||||
return resultSetMetaData.getColumnDisplaySize(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnLabel(final int column) throws SQLException {
|
||||
return resultSetMetaData.getColumnLabel(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(final int column) throws SQLException {
|
||||
if (sqlStatementContext instanceof SelectStatementContext) {
|
||||
List<Projection> actualProjections = ((SelectStatementContext) sqlStatementContext).getProjectionsContext().getExpandProjections();
|
||||
if (column > actualProjections.size()) {
|
||||
throw new SQLException("Column index out of range.", "S1002", 0);
|
||||
}
|
||||
Projection projection = ((SelectStatementContext) sqlStatementContext).getProjectionsContext().getExpandProjections().get(column - 1);
|
||||
if (projection instanceof ColumnProjection) {
|
||||
return ((ColumnProjection) projection).getName();
|
||||
}
|
||||
}
|
||||
return resultSetMetaData.getColumnName(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSchemaName(final int column) {
|
||||
return DefaultSchema.LOGIC_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrecision(final int column) throws SQLException {
|
||||
return resultSetMetaData.getPrecision(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getScale(final int column) throws SQLException {
|
||||
return resultSetMetaData.getScale(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName(final int column) throws SQLException {
|
||||
String actualTableName = resultSetMetaData.getTableName(column);
|
||||
return actualTableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCatalogName(final int column) {
|
||||
return DefaultSchema.LOGIC_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnType(final int column) throws SQLException {
|
||||
return resultSetMetaData.getColumnType(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnTypeName(final int column) throws SQLException {
|
||||
return resultSetMetaData.getColumnTypeName(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly(final int column) throws SQLException {
|
||||
return resultSetMetaData.isReadOnly(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWritable(final int column) throws SQLException {
|
||||
return resultSetMetaData.isWritable(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefinitelyWritable(final int column) throws SQLException {
|
||||
return resultSetMetaData.isDefinitelyWritable(column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnClassName(final int column) throws SQLException {
|
||||
return resultSetMetaData.getColumnClassName(column);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
package cn.fateverse.query.submeter.unsupported;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.sql.*;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2024/4/7 16:58
|
||||
*/
|
||||
public abstract class AbstractUnsupportedOperationResultSet extends AbstractUnsupportedUpdateOperationResultSet {
|
||||
|
||||
@Override
|
||||
public boolean previous() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("previous");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBeforeFirst() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("isBeforeFirst");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAfterLast() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("isAfterLast");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFirst() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("isFirst");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLast() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("isLast");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeFirst() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("beforeFirst");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterLast() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("afterLast");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean first() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("first");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean last() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("last");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean absolute(final int row) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("absolute");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean relative(final int rows) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("relative");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRow() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getRow");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void insertRow() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("insertRow");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateRow() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateRow");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void deleteRow() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("deleteRow");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void refreshRow() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("refreshRow");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void cancelRowUpdates() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("cancelRowUpdates");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void moveToInsertRow() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("moveToInsertRow");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void moveToCurrentRow() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("moveToCurrentRow");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean rowInserted() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("rowInserted");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean rowUpdated() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("rowUpdated");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean rowDeleted() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("rowDeleted");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getCursorName() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getCursorName");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getHoldability() throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getHoldability");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getNString(final int columnIndex) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getNString");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getNString(final String columnLabel) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getNString");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final NClob getNClob(final int columnIndex) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getNClob");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final NClob getNClob(final String columnLabel) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getNClob");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Reader getNCharacterStream(final int columnIndex) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getNCharacterStream");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Reader getNCharacterStream(final String columnLabel) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getNCharacterStream");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Ref getRef(final int columnIndex) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getRef");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Ref getRef(final String columnLabel) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getRef");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Array getArray(final int columnIndex) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getArray");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Array getArray(final String columnLabel) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getArray");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final RowId getRowId(final int columnIndex) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getRowId");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final RowId getRowId(final String columnLabel) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getRowId");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <T> T getObject(final int columnIndex, final Class<T> type) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getObject with type");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <T> T getObject(final String columnLabel, final Class<T> type) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getObject with type");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Object getObject(final String columnLabel, final Map<String, Class<?>> map) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getObject with map");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Object getObject(final int columnIndex, final Map<String, Class<?>> map) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("getObject with map");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,425 @@
|
||||
package cn.fateverse.query.submeter.unsupported;
|
||||
|
||||
import cn.fateverse.query.submeter.adapter.WrapperAdapter;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.*;
|
||||
|
||||
/**
|
||||
* @author Clay
|
||||
* @date 2024/4/7 16:57
|
||||
*/
|
||||
public abstract class AbstractUnsupportedUpdateOperationResultSet extends WrapperAdapter implements ResultSet {
|
||||
|
||||
@Override
|
||||
public final void updateNull(final int columnIndex) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateNull(final String columnLabel) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBoolean(final int columnIndex, final boolean x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBoolean(final String columnLabel, final boolean x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateByte(final int columnIndex, final byte x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateByte(final String columnLabel, final byte x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateShort(final int columnIndex, final short x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateShort(final String columnLabel, final short x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateInt(final int columnIndex, final int x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateInt(final String columnLabel, final int x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateLong(final int columnIndex, final long x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateLong(final String columnLabel, final long x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateFloat(final int columnIndex, final float x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateFloat(final String columnLabel, final float x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateDouble(final int columnIndex, final double x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateDouble(final String columnLabel, final double x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBigDecimal(final int columnIndex, final BigDecimal x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBigDecimal(final String columnLabel, final BigDecimal x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateString(final int columnIndex, final String x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateString(final String columnLabel, final String x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateNString(final int columnIndex, final String nString) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateNString(final String columnLabel, final String nString) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBytes(final int columnIndex, final byte[] x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBytes(final String columnLabel, final byte[] x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateDate(final int columnIndex, final Date x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateDate(final String columnLabel, final Date x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateTime(final int columnIndex, final Time x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateTime(final String columnLabel, final Time x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateTimestamp(final int columnIndex, final Timestamp x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateTimestamp(final String columnLabel, final Timestamp x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateAsciiStream(final int columnIndex, final InputStream inputStream) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateAsciiStream(final String columnLabel, final InputStream inputStream) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateAsciiStream(final int columnIndex, final InputStream x, final int length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateAsciiStream(final String columnLabel, final InputStream x, final int length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateAsciiStream(final int columnIndex, final InputStream inputStream, final long length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateAsciiStream(final String columnLabel, final InputStream inputStream, final long length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBinaryStream(final int columnIndex, final InputStream x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBinaryStream(final String columnLabel, final InputStream x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBinaryStream(final int columnIndex, final InputStream x, final int length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBinaryStream(final String columnLabel, final InputStream x, final int length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBinaryStream(final int columnIndex, final InputStream x, final long length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBinaryStream(final String columnLabel, final InputStream x, final long length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateCharacterStream(final int columnIndex, final Reader x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateCharacterStream(final String columnLabel, final Reader x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateCharacterStream(final int columnIndex, final Reader x, final int length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateCharacterStream(final String columnLabel, final Reader reader, final int length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateCharacterStream(final int columnIndex, final Reader x, final long length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateCharacterStream(final String columnLabel, final Reader reader, final long length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateNCharacterStream(final int columnIndex, final Reader x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateNCharacterStream(final String columnLabel, final Reader x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateNCharacterStream(final int columnIndex, final Reader x, final long length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateNCharacterStream(final String columnLabel, final Reader x, final long length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateObject(final int columnIndex, final Object x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateObject(final String columnLabel, final Object x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateObject(final int columnIndex, final Object x, final int scaleOrLength) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateObject(final String columnLabel, final Object x, final int scaleOrLength) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateRef(final int columnIndex, final Ref x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateRef(final String columnLabel, final Ref x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBlob(final int columnIndex, final Blob x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBlob(final String columnLabel, final Blob x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBlob(final int columnIndex, final InputStream inputStream) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBlob(final String columnLabel, final InputStream inputStream) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBlob(final int columnIndex, final InputStream inputStream, final long length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateBlob(final String columnLabel, final InputStream inputStream, final long length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateClob(final int columnIndex, final Clob x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateClob(final String columnLabel, final Clob x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateClob(final int columnIndex, final Reader reader) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateClob(final String columnLabel, final Reader reader) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateClob(final int columnIndex, final Reader reader, final long length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateClob(final String columnLabel, final Reader reader, final long length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateNClob(final int columnIndex, final NClob nClob) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateNClob(final String columnLabel, final NClob nClob) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateNClob(final int columnIndex, final Reader reader) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateNClob(final String columnLabel, final Reader reader) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateNClob(final int columnIndex, final Reader reader, final long length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateNClob(final String columnLabel, final Reader reader, final long length) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateArray(final int columnIndex, final Array x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateArray(final String columnLabel, final Array x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateRowId(final int columnIndex, final RowId x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateRowId(final String columnLabel, final RowId x) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateSQLXML(final int columnIndex, final SQLXML xmlObject) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void updateSQLXML(final String columnLabel, final SQLXML xmlObject) throws SQLException {
|
||||
throw new SQLFeatureNotSupportedException("updateXXX");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package cn.fateverse.query.submeter.util;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public final class DataSourceUtil {
|
||||
|
||||
private static final String SET_METHOD_PREFIX = "set";
|
||||
|
||||
private static Collection<Class<?>> generalClassType;
|
||||
|
||||
static {
|
||||
generalClassType = new HashSet<>();
|
||||
Collections.addAll(generalClassType,boolean.class, Boolean.class, int.class, Integer.class, long.class, Long.class, String.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data source.
|
||||
*
|
||||
* @param dataSourceClassName data source class name
|
||||
* @param dataSourceProperties data source properties
|
||||
* @return data source instance
|
||||
* @throws ReflectiveOperationException reflective operation exception
|
||||
*/
|
||||
public static DataSource getDataSource(final String dataSourceClassName, final Map<String, Object> dataSourceProperties) throws ReflectiveOperationException {
|
||||
DataSource result = (DataSource) Class.forName(dataSourceClassName).newInstance();
|
||||
for (Entry<String, Object> entry : dataSourceProperties.entrySet()) {
|
||||
callSetterMethod(result, getSetterMethodName(entry.getKey()), null == entry.getValue() ? null : entry.getValue().toString());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String getSetterMethodName(final String propertyName) {
|
||||
if (propertyName.contains("-")) {
|
||||
return CaseFormat.LOWER_HYPHEN.to(CaseFormat.LOWER_CAMEL, SET_METHOD_PREFIX + "-" + propertyName);
|
||||
}
|
||||
return SET_METHOD_PREFIX + String.valueOf(propertyName.charAt(0)).toUpperCase() + propertyName.substring(1, propertyName.length());
|
||||
}
|
||||
|
||||
private static void callSetterMethod(final DataSource dataSource, final String methodName, final String setterValue) {
|
||||
for (Class<?> each : generalClassType) {
|
||||
try {
|
||||
Method method = dataSource.getClass().getMethod(methodName, each);
|
||||
if (boolean.class == each || Boolean.class == each) {
|
||||
method.invoke(dataSource, Boolean.valueOf(setterValue));
|
||||
} else if (int.class == each || Integer.class == each) {
|
||||
method.invoke(dataSource, Integer.parseInt(setterValue));
|
||||
} else if (long.class == each || Long.class == each) {
|
||||
method.invoke(dataSource, Long.parseLong(setterValue));
|
||||
} else {
|
||||
method.invoke(dataSource, setterValue);
|
||||
}
|
||||
return;
|
||||
} catch (final ReflectiveOperationException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package cn.fateverse.query.submeter.util;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.beans.factory.config.PlaceholderConfigurerSupport;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.PropertyResolver;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public final class PropertyUtil {
|
||||
|
||||
private static int springBootVersion = 1;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class.forName("org.springframework.boot.bind.RelaxedPropertyResolver");
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
springBootVersion = 2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Spring Boot 1.x is compatible with Spring Boot 2.x by Using Java Reflect.
|
||||
* @param environment : the environment context
|
||||
* @param prefix : the prefix part of property key
|
||||
* @param targetClass : the target class type of result
|
||||
* @param <T> : refer to @param targetClass
|
||||
* @return T
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T handle(final Environment environment, final String prefix, final Class<T> targetClass) {
|
||||
switch (springBootVersion) {
|
||||
case 1:
|
||||
return (T) v1(environment, prefix);
|
||||
default:
|
||||
return (T) v2(environment, prefix, targetClass);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@SneakyThrows
|
||||
private static Object v1(final Environment environment, final String prefix) {
|
||||
Class<?> resolverClass = Class.forName("org.springframework.boot.bind.RelaxedPropertyResolver");
|
||||
Constructor<?> resolverConstructor = resolverClass.getDeclaredConstructor(PropertyResolver.class);
|
||||
Method getSubPropertiesMethod = resolverClass.getDeclaredMethod("getSubProperties", String.class);
|
||||
Object resolverObject = resolverConstructor.newInstance(environment);
|
||||
String prefixParam = prefix.endsWith(".") ? prefix : prefix + ".";
|
||||
Method getPropertyMethod = resolverClass.getDeclaredMethod("getProperty", String.class);
|
||||
Map<String, Object> dataSourceProps = (Map<String, Object>) getSubPropertiesMethod.invoke(resolverObject, prefixParam);
|
||||
Map<String, Object> propertiesWithPlaceholderResolved = new HashMap<>();
|
||||
for (Map.Entry<String, Object> entry : dataSourceProps.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof String && ((String) value).contains(
|
||||
PlaceholderConfigurerSupport.DEFAULT_PLACEHOLDER_PREFIX)) {
|
||||
String resolvedValue = (String) getPropertyMethod.invoke(resolverObject, prefixParam + key);
|
||||
propertiesWithPlaceholderResolved.put(key, resolvedValue);
|
||||
} else {
|
||||
propertiesWithPlaceholderResolved.put(key, value);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableMap(propertiesWithPlaceholderResolved);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private static Object v2(final Environment environment, final String prefix, final Class<?> targetClass) {
|
||||
Class<?> binderClass = Class.forName("org.springframework.boot.context.properties.bind.Binder");
|
||||
Method getMethod = binderClass.getDeclaredMethod("get", Environment.class);
|
||||
Method bindMethod = binderClass.getDeclaredMethod("bind", String.class, Class.class);
|
||||
Object binderObject = getMethod.invoke(null, environment);
|
||||
String prefixParam = prefix.endsWith(".") ? prefix.substring(0, prefix.length() - 1) : prefix;
|
||||
Object bindResultObject = bindMethod.invoke(binderObject, prefixParam, targetClass);
|
||||
Method resultGetMethod = bindResultObject.getClass().getDeclaredMethod("get");
|
||||
return resultGetMethod.invoke(bindResultObject);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package cn.fateverse.query.submeter.util;
|
||||
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import com.google.common.primitives.Longs;
|
||||
import com.google.common.primitives.Shorts;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Date;
|
||||
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public final class ResultSetUtil {
|
||||
|
||||
/**
|
||||
* Convert value via expected class type.
|
||||
*
|
||||
* @param value original value
|
||||
* @param convertType expected class type
|
||||
* @return converted value
|
||||
*/
|
||||
public static Object convertValue(final Object value, final Class<?> convertType) {
|
||||
if (null == value) {
|
||||
return convertNullValue(convertType);
|
||||
}
|
||||
if (value.getClass() == convertType) {
|
||||
return value;
|
||||
}
|
||||
if (value instanceof Number) {
|
||||
return convertNumberValue(value, convertType);
|
||||
}
|
||||
if (value instanceof Date) {
|
||||
return convertDateValue(value, convertType);
|
||||
}
|
||||
if (value instanceof byte[]) {
|
||||
return convertByteArrayValue(value, convertType);
|
||||
}
|
||||
if (String.class.equals(convertType)) {
|
||||
return value.toString();
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private static Object convertNullValue(final Class<?> convertType) {
|
||||
switch (convertType.getName()) {
|
||||
case "boolean":
|
||||
return false;
|
||||
case "byte":
|
||||
return (byte) 0;
|
||||
case "short":
|
||||
return (short) 0;
|
||||
case "int":
|
||||
return 0;
|
||||
case "long":
|
||||
return 0L;
|
||||
case "float":
|
||||
return 0F;
|
||||
case "double":
|
||||
return 0D;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Object convertNumberValue(final Object value, final Class<?> convertType) {
|
||||
Number number = (Number) value;
|
||||
switch (convertType.getName()) {
|
||||
case "boolean":
|
||||
return 0 != number.longValue();
|
||||
case "byte":
|
||||
return number.byteValue();
|
||||
case "short":
|
||||
return number.shortValue();
|
||||
case "int":
|
||||
return number.intValue();
|
||||
case "long":
|
||||
return number.longValue();
|
||||
case "double":
|
||||
return number.doubleValue();
|
||||
case "float":
|
||||
return number.floatValue();
|
||||
case "java.math.BigDecimal":
|
||||
return new BigDecimal(number.toString());
|
||||
case "java.lang.Object":
|
||||
return value;
|
||||
case "java.lang.String":
|
||||
return value.toString();
|
||||
default:
|
||||
// throw new ShardingSphereException("Unsupported data type: %s", convertType);
|
||||
throw new RuntimeException("Unsupported data type: " + convertType);
|
||||
}
|
||||
}
|
||||
|
||||
private static Object convertDateValue(final Object value, final Class<?> convertType) {
|
||||
Date date = (Date) value;
|
||||
switch (convertType.getName()) {
|
||||
case "java.sql.Date":
|
||||
return new java.sql.Date(date.getTime());
|
||||
case "java.sql.Time":
|
||||
return new Time(date.getTime());
|
||||
case "java.sql.Timestamp":
|
||||
return new Timestamp(date.getTime());
|
||||
case "java.lang.String":
|
||||
return date.toString();
|
||||
default:
|
||||
// throw new ShardingSphereException("Unsupported Date type: %s", convertType);
|
||||
throw new RuntimeException("Unsupported data type: " + convertType);
|
||||
}
|
||||
}
|
||||
|
||||
private static Object convertByteArrayValue(final Object value, final Class<?> convertType) {
|
||||
byte[] bytesValue = (byte[]) value;
|
||||
switch (bytesValue.length) {
|
||||
case 1:
|
||||
return convertNumberValue(bytesValue[0], convertType);
|
||||
case Shorts.BYTES:
|
||||
return convertNumberValue(Shorts.fromByteArray(bytesValue), convertType);
|
||||
case Ints.BYTES:
|
||||
return convertNumberValue(Ints.fromByteArray(bytesValue), convertType);
|
||||
case Longs.BYTES:
|
||||
return convertNumberValue(Longs.fromByteArray(bytesValue), convertType);
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user