feat : 模块抽离 + 自定义查分表模块基本完成

This commit is contained in:
clay
2024-04-10 14:31:08 +08:00
parent da94c4fa32
commit cde8e3a928
377 changed files with 3249 additions and 136 deletions

View 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>

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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");
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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)");
}
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,4 @@
package cn.fateverse.query.submeter.datasource;
public class SubmeterDataSourceFactory {
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}

View File

@@ -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();
}
}

View File

@@ -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");
}
}

View File

@@ -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");
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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");
}
}

View File

@@ -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");
}
}

View File

@@ -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) {
}
}
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}