[Core] [Driver] [Redis] Fixed code style

This commit is contained in:
qianmoQ 2023-03-06 10:23:37 +08:00
parent edabab88c9
commit 9c2e3bb95d
25 changed files with 2301 additions and 805 deletions

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
isCompile=0 isCompile=0
folders='core,plugin,client,lib' folders='core,plugin,client,lib,driver'
printf "Code verification before submission starting\n" printf "Code verification before submission starting\n"

View File

@ -6,7 +6,7 @@
<parent> <parent>
<artifactId>datacap</artifactId> <artifactId>datacap</artifactId>
<groupId>io.edurt.datacap</groupId> <groupId>io.edurt.datacap</groupId>
<version>1.6.0</version> <version>1.7.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
@ -15,19 +15,19 @@
<description>DataCap - Driver</description> <description>DataCap - Driver</description>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <redis.version>3.6.3</redis.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>redis.clients</groupId> <groupId>redis.clients</groupId>
<artifactId>jedis</artifactId> <artifactId>jedis</artifactId>
<version>${redis.version}</version> <version>${redis.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>findbugs</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -9,7 +9,8 @@ import lombok.NoArgsConstructor;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class Hint { public class Hint
{
/** /**
* hint key * hint key
*/ */

View File

@ -3,12 +3,14 @@ package io.edurt.datacap.core;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects; import java.util.Objects;
public enum HintKey { public enum HintKey
{
decoder, decoder,
sample_key, sample_key,
noop; noop;
public static HintKey fromString(String string) { public static HintKey fromString(String string)
{
return Arrays.stream(values()) return Arrays.stream(values())
.filter(t -> Objects.equals(t.toString(), string)) .filter(t -> Objects.equals(t.toString(), string))
.findFirst() .findFirst()

View File

@ -2,14 +2,17 @@ package io.edurt.datacap.core;
import java.util.Arrays; import java.util.Arrays;
public class Logger { public class Logger
{
private final Class<?> mark; private final Class<?> mark;
public Logger(Class<?> mark) { public Logger(Class<?> mark)
{
this.mark = mark; this.mark = mark;
} }
public synchronized void log(String format, Object... arguments) { public synchronized void log(String format, Object... arguments)
{
Object[] objs = Arrays.stream(arguments) Object[] objs = Arrays.stream(arguments)
.map(t -> { .map(t -> {
if (t instanceof Throwable) { if (t instanceof Throwable) {

View File

@ -1,5 +1,6 @@
package io.edurt.datacap.core; package io.edurt.datacap.core;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@ -9,24 +10,27 @@ import java.util.List;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class Op { @SuppressFBWarnings(value = {"EI_EXPOSE_REP", "EI_EXPOSE_REP2"},
justification = "I prefer to suppress these FindBugs warnings")
public class Op
{
/** /**
* 执行的原始SQL * Executed original SQL
*/ */
private String originSql; private String originSql;
/** /**
* SQL中解析出来的hint * Hint parsed from SQL
*/ */
private List<Hint> hints; private List<Hint> hints;
/** /**
* SQL中解析出来的command * COMMAND parsed from SQL
*/ */
private String command; private String command;
/** /**
* SQL解析出来的参数 * Parameters parsed by SQL
*/ */
private String[] params; private String[] params;
} }

View File

@ -2,10 +2,13 @@ package io.edurt.datacap.core;
import java.sql.SQLException; import java.sql.SQLException;
public interface RedisClient { public interface RedisClient
String[] sendCommand(String sql) throws SQLException; {
String[] sendCommand(String sql)
throws SQLException;
void select(int dbIndex) throws SQLException; void select(int dbIndex)
throws SQLException;
void close(); void close();
} }

View File

@ -5,7 +5,9 @@ import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
public class RedisConnection implements Connection { public class RedisConnection
implements Connection
{
private final static Logger LOGGER = new Logger(RedisConnection.class); private final static Logger LOGGER = new Logger(RedisConnection.class);
private final RedisClient redisClient; private final RedisClient redisClient;
@ -13,7 +15,8 @@ public class RedisConnection implements Connection {
private String dbIndex; private String dbIndex;
public RedisConnection(RedisClient redisClient, String dbIndex, Properties properties) { public RedisConnection(RedisClient redisClient, String dbIndex, Properties properties)
{
this.redisClient = redisClient; this.redisClient = redisClient;
this.dbIndex = dbIndex; this.dbIndex = dbIndex;
this.properties = properties; this.properties = properties;
@ -21,227 +24,308 @@ public class RedisConnection implements Connection {
private boolean isClosed = false; private boolean isClosed = false;
@Override @Override
public Statement createStatement() throws SQLException { public Statement createStatement()
throws SQLException
{
this.checkClosed(); this.checkClosed();
return new RedisStatement(this, this.redisClient); return new RedisStatement(this, this.redisClient);
} }
@Override @Override
public PreparedStatement prepareStatement(String sql) throws SQLException { public PreparedStatement prepareStatement(String sql)
throws SQLException
{
// TODO 暂不实现感觉意义不大未来看是否需要实现 // TODO 暂不实现感觉意义不大未来看是否需要实现
LOGGER.log("prepareStatement not implemented"); LOGGER.log("prepareStatement not implemented");
throw new SQLFeatureNotSupportedException("prepareStatement not implemented"); throw new SQLFeatureNotSupportedException("prepareStatement not implemented");
} }
@Override @Override
public CallableStatement prepareCall(String sql) throws SQLException { public CallableStatement prepareCall(String sql)
throws SQLException
{
// TODO 暂不实现感觉无意义因为主要是执行存储过程的redis没这玩意 // TODO 暂不实现感觉无意义因为主要是执行存储过程的redis没这玩意
LOGGER.log("prepareCall not implemented"); LOGGER.log("prepareCall not implemented");
throw new SQLFeatureNotSupportedException("prepareCall not implemented"); throw new SQLFeatureNotSupportedException("prepareCall not implemented");
} }
@Override @Override
public String nativeSQL(String sql) throws SQLException { public String nativeSQL(String sql)
throws SQLException
{
LOGGER.log("nativeSQL not implemented"); LOGGER.log("nativeSQL not implemented");
throw new SQLFeatureNotSupportedException("nativeSQL not implemented"); throw new SQLFeatureNotSupportedException("nativeSQL not implemented");
} }
@Override @Override
public void setAutoCommit(boolean autoCommit) throws SQLException { public void setAutoCommit(boolean autoCommit)
throws SQLException
{
} }
@Override @Override
public boolean getAutoCommit() throws SQLException { public boolean getAutoCommit()
throws SQLException
{
return true; return true;
} }
@Override @Override
public void commit() throws SQLException { public void commit()
throws SQLException
{
// TODO 待支持事务 // TODO 待支持事务
} }
@Override @Override
public void rollback() throws SQLException { public void rollback()
throws SQLException
{
// TODO // TODO
} }
@Override @Override
public void close() throws SQLException { public void close()
throws SQLException
{
this.redisClient.close(); this.redisClient.close();
LOGGER.log("Connection close"); LOGGER.log("Connection close");
this.isClosed = true; this.isClosed = true;
} }
@Override @Override
public boolean isClosed() throws SQLException { public boolean isClosed()
throws SQLException
{
LOGGER.log("Connection isClosed = %s", isClosed); LOGGER.log("Connection isClosed = %s", isClosed);
return this.isClosed; return this.isClosed;
} }
@Override @Override
public DatabaseMetaData getMetaData() throws SQLException { public DatabaseMetaData getMetaData()
throws SQLException
{
return new RedisDatabaseMetadata(this, this.dbIndex); return new RedisDatabaseMetadata(this, this.dbIndex);
} }
@Override @Override
public void setReadOnly(boolean readOnly) throws SQLException { public void setReadOnly(boolean readOnly)
throws SQLException
{
// do nothing // do nothing
} }
@Override @Override
public boolean isReadOnly() throws SQLException { public boolean isReadOnly()
throws SQLException
{
return false; return false;
} }
@Override @Override
public void setCatalog(String catalog) throws SQLException { public void setCatalog(String catalog)
throws SQLException
{
LOGGER.log("setCatalog(%s)", catalog); LOGGER.log("setCatalog(%s)", catalog);
// do nothing // do nothing
} }
@Override @Override
public String getCatalog() throws SQLException { public String getCatalog()
throws SQLException
{
return null; return null;
} }
@Override @Override
public void setTransactionIsolation(int level) throws SQLException { public void setTransactionIsolation(int level)
throws SQLException
{
} }
@Override @Override
public int getTransactionIsolation() throws SQLException { public int getTransactionIsolation()
throws SQLException
{
return Connection.TRANSACTION_NONE; return Connection.TRANSACTION_NONE;
} }
@Override @Override
public SQLWarning getWarnings() throws SQLException { public SQLWarning getWarnings()
throws SQLException
{
LOGGER.log("getWarnings returns null"); LOGGER.log("getWarnings returns null");
return null; return null;
} }
@Override @Override
public void clearWarnings() throws SQLException { public void clearWarnings()
throws SQLException
{
} }
@Override @Override
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { public Statement createStatement(int resultSetType, int resultSetConcurrency)
throws SQLException
{
return this.createStatement(); return this.createStatement();
} }
@Override @Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
throws SQLException
{
return this.prepareStatement(sql); return this.prepareStatement(sql);
} }
@Override @Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency)
throws SQLException
{
return this.prepareCall(sql); return this.prepareCall(sql);
} }
@Override @Override
public Map<String, Class<?>> getTypeMap() throws SQLException { public Map<String, Class<?>> getTypeMap()
throws SQLException
{
LOGGER.log("getTypeMap not implemented"); LOGGER.log("getTypeMap not implemented");
throw new SQLFeatureNotSupportedException("getTypeMap not implemented"); throw new SQLFeatureNotSupportedException("getTypeMap not implemented");
} }
@Override @Override
public void setTypeMap(Map<String, Class<?>> map) throws SQLException { public void setTypeMap(Map<String, Class<?>> map)
throws SQLException
{
LOGGER.log("setTypeMap not implemented"); LOGGER.log("setTypeMap not implemented");
throw new SQLFeatureNotSupportedException("setTypeMap not implemented"); throw new SQLFeatureNotSupportedException("setTypeMap not implemented");
} }
@Override @Override
public void setHoldability(int holdability) throws SQLException { public void setHoldability(int holdability)
throws SQLException
{
// do nothing // do nothing
} }
@Override @Override
public int getHoldability() throws SQLException { public int getHoldability()
throws SQLException
{
return ResultSet.HOLD_CURSORS_OVER_COMMIT; return ResultSet.HOLD_CURSORS_OVER_COMMIT;
} }
@Override @Override
public Savepoint setSavepoint() throws SQLException { public Savepoint setSavepoint()
throws SQLException
{
LOGGER.log("setSavepoint not implemented"); LOGGER.log("setSavepoint not implemented");
throw new SQLFeatureNotSupportedException("setSavepoint not implemented"); throw new SQLFeatureNotSupportedException("setSavepoint not implemented");
} }
@Override @Override
public Savepoint setSavepoint(String name) throws SQLException { public Savepoint setSavepoint(String name)
throws SQLException
{
LOGGER.log("setSavepoint not implemented"); LOGGER.log("setSavepoint not implemented");
throw new SQLFeatureNotSupportedException("setSavepoint not implemented"); throw new SQLFeatureNotSupportedException("setSavepoint not implemented");
} }
@Override @Override
public void rollback(Savepoint savepoint) throws SQLException { public void rollback(Savepoint savepoint)
throws SQLException
{
LOGGER.log("rollback not implemented"); LOGGER.log("rollback not implemented");
throw new SQLFeatureNotSupportedException("rollback not implemented"); throw new SQLFeatureNotSupportedException("rollback not implemented");
} }
@Override @Override
public void releaseSavepoint(Savepoint savepoint) throws SQLException { public void releaseSavepoint(Savepoint savepoint)
throws SQLException
{
LOGGER.log("releaseSavepoint not implemented"); LOGGER.log("releaseSavepoint not implemented");
throw new SQLFeatureNotSupportedException("releaseSavepoint not implemented"); throw new SQLFeatureNotSupportedException("releaseSavepoint not implemented");
} }
@Override @Override
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException
{
return this.createStatement(); return this.createStatement();
} }
@Override @Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException
{
return this.prepareStatement(sql); return this.prepareStatement(sql);
} }
@Override @Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException
{
return this.prepareCall(sql); return this.prepareCall(sql);
} }
@Override @Override
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
throws SQLException
{
return this.prepareStatement(sql); return this.prepareStatement(sql);
} }
@Override @Override
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
throws SQLException
{
return this.prepareStatement(sql); return this.prepareStatement(sql);
} }
@Override @Override
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { public PreparedStatement prepareStatement(String sql, String[] columnNames)
throws SQLException
{
return this.prepareStatement(sql); return this.prepareStatement(sql);
} }
@Override @Override
public Clob createClob() throws SQLException { public Clob createClob()
throws SQLException
{
LOGGER.log("createClob not implemented"); LOGGER.log("createClob not implemented");
throw new SQLFeatureNotSupportedException("createClob not implemented"); throw new SQLFeatureNotSupportedException("createClob not implemented");
} }
@Override @Override
public Blob createBlob() throws SQLException { public Blob createBlob()
throws SQLException
{
LOGGER.log("createBlob not implemented"); LOGGER.log("createBlob not implemented");
throw new SQLFeatureNotSupportedException("createBlob not implemented"); throw new SQLFeatureNotSupportedException("createBlob not implemented");
} }
@Override @Override
public NClob createNClob() throws SQLException { public NClob createNClob()
throws SQLException
{
LOGGER.log("createNClob not implemented"); LOGGER.log("createNClob not implemented");
throw new SQLFeatureNotSupportedException("createNClob not implemented"); throw new SQLFeatureNotSupportedException("createNClob not implemented");
} }
@Override @Override
public SQLXML createSQLXML() throws SQLException { public SQLXML createSQLXML()
throws SQLException
{
LOGGER.log("createSQLXML not implemented"); LOGGER.log("createSQLXML not implemented");
throw new SQLFeatureNotSupportedException("createSQLXML not implemented"); throw new SQLFeatureNotSupportedException("createSQLXML not implemented");
} }
@Override @Override
public boolean isValid(int timeout) throws SQLException { public boolean isValid(int timeout)
throws SQLException
{
LOGGER.log("isValid = %s", isClosed); LOGGER.log("isValid = %s", isClosed);
if (this.isClosed) { if (this.isClosed) {
return false; return false;
@ -250,23 +334,30 @@ public class RedisConnection implements Connection {
try { try {
this.redisClient.sendCommand("PING"); this.redisClient.sendCommand("PING");
return true; return true;
} catch (Exception e) { }
catch (Exception e) {
return false; return false;
} }
} }
@Override @Override
public void setClientInfo(String name, String value) throws SQLClientInfoException { public void setClientInfo(String name, String value)
throws SQLClientInfoException
{
this.properties.put(name, value); this.properties.put(name, value);
} }
@Override @Override
public void setClientInfo(Properties properties) throws SQLClientInfoException { public void setClientInfo(Properties properties)
throws SQLClientInfoException
{
this.properties.putAll(properties); this.properties.putAll(properties);
} }
@Override @Override
public String getClientInfo(String name) throws SQLException { public String getClientInfo(String name)
throws SQLException
{
this.checkClosed(); this.checkClosed();
String property = this.properties.getProperty(name); String property = this.properties.getProperty(name);
@ -276,25 +367,33 @@ public class RedisConnection implements Connection {
} }
@Override @Override
public Properties getClientInfo() throws SQLException { public Properties getClientInfo()
throws SQLException
{
LOGGER.log("getClientInfo() = %s", properties); LOGGER.log("getClientInfo() = %s", properties);
return this.properties; return this.properties;
} }
@Override @Override
public Array createArrayOf(String typeName, Object[] elements) throws SQLException { public Array createArrayOf(String typeName, Object[] elements)
throws SQLException
{
LOGGER.log("createArrayOf not implemented"); LOGGER.log("createArrayOf not implemented");
throw new SQLFeatureNotSupportedException("createArrayOf not implemented"); throw new SQLFeatureNotSupportedException("createArrayOf not implemented");
} }
@Override @Override
public Struct createStruct(String typeName, Object[] attributes) throws SQLException { public Struct createStruct(String typeName, Object[] attributes)
throws SQLException
{
LOGGER.log("createStruct not implemented"); LOGGER.log("createStruct not implemented");
throw new SQLFeatureNotSupportedException("createStruct not implemented"); throw new SQLFeatureNotSupportedException("createStruct not implemented");
} }
@Override @Override
public void setSchema(String schema) throws SQLException { public void setSchema(String schema)
throws SQLException
{
synchronized (RedisConnection.class) { synchronized (RedisConnection.class) {
LOGGER.log("setSchema(%s)", schema); LOGGER.log("setSchema(%s)", schema);
this.checkClosed(); this.checkClosed();
@ -306,7 +405,9 @@ public class RedisConnection implements Connection {
} }
@Override @Override
public String getSchema() throws SQLException { public String getSchema()
throws SQLException
{
synchronized (RedisConnection.class) { synchronized (RedisConnection.class) {
this.checkClosed(); this.checkClosed();
LOGGER.log("getSchema() = %s", this.dbIndex); LOGGER.log("getSchema() = %s", this.dbIndex);
@ -315,40 +416,53 @@ public class RedisConnection implements Connection {
} }
@Override @Override
public void abort(Executor executor) throws SQLException { public void abort(Executor executor)
throws SQLException
{
LOGGER.log("abort not implemented"); LOGGER.log("abort not implemented");
throw new SQLFeatureNotSupportedException("abort not implemented"); throw new SQLFeatureNotSupportedException("abort not implemented");
} }
@Override @Override
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException { public void setNetworkTimeout(Executor executor, int milliseconds)
throws SQLException
{
LOGGER.log("setNetworkTimeout not implemented"); LOGGER.log("setNetworkTimeout not implemented");
throw new SQLFeatureNotSupportedException("setNetworkTimeout not implemented"); throw new SQLFeatureNotSupportedException("setNetworkTimeout not implemented");
} }
@Override @Override
public int getNetworkTimeout() throws SQLException { public int getNetworkTimeout()
throws SQLException
{
LOGGER.log("getNetworkTimeout not implemented"); LOGGER.log("getNetworkTimeout not implemented");
throw new SQLFeatureNotSupportedException("getNetworkTimeout not implemented"); throw new SQLFeatureNotSupportedException("getNetworkTimeout not implemented");
} }
@Override @Override
public <T> T unwrap(Class<T> iface) throws SQLException { public <T> T unwrap(Class<T> iface)
throws SQLException
{
try { try {
return iface.cast(this); return iface.cast(this);
} catch (ClassCastException cce) { }
catch (ClassCastException cce) {
LOGGER.log("Unable to unwrap to %s", iface); LOGGER.log("Unable to unwrap to %s", iface);
throw new SQLException("Unable to unwrap to " + iface); throw new SQLException("Unable to unwrap to " + iface);
} }
} }
@Override @Override
public boolean isWrapperFor(Class<?> iface) throws SQLException { public boolean isWrapperFor(Class<?> iface)
throws SQLException
{
this.checkClosed(); this.checkClosed();
return iface.isInstance(this); return iface.isInstance(this);
} }
private void checkClosed() throws SQLException { private void checkClosed()
throws SQLException
{
if (isClosed()) { if (isClosed()) {
LOGGER.log("Connection is closed."); LOGGER.log("Connection is closed.");
throw new SQLException("Connection is closed."); throw new SQLException("Connection is closed.");

View File

@ -4,130 +4,178 @@ import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Types; import java.sql.Types;
public class RedisResultSetMetaData implements ResultSetMetaData { public class RedisResultSetMetaData
implements ResultSetMetaData
{
private final static Logger LOGGER = new Logger(RedisResultSetMetaData.class); private final static Logger LOGGER = new Logger(RedisResultSetMetaData.class);
public static final int MAX_SIZE = 1024; public static final int MAX_SIZE = 1024;
@Override @Override
public <T> T unwrap(Class<T> iface) throws SQLException { public <T> T unwrap(Class<T> iface)
throws SQLException
{
try { try {
return iface.cast(this); return iface.cast(this);
} catch (ClassCastException cce) { }
catch (ClassCastException cce) {
LOGGER.log("Unable to unwrap to %s", iface); LOGGER.log("Unable to unwrap to %s", iface);
throw new SQLException("Unable to unwrap to " + iface); throw new SQLException("Unable to unwrap to " + iface);
} }
} }
@Override @Override
public boolean isWrapperFor(Class<?> iface) throws SQLException { public boolean isWrapperFor(Class<?> iface)
throws SQLException
{
return iface.isInstance(this); return iface.isInstance(this);
} }
@Override @Override
public int getColumnCount() throws SQLException { public int getColumnCount()
throws SQLException
{
return 1; return 1;
} }
@Override @Override
public boolean isAutoIncrement(int column) throws SQLException { public boolean isAutoIncrement(int column)
throws SQLException
{
return false; return false;
} }
@Override @Override
public boolean isCaseSensitive(int column) throws SQLException { public boolean isCaseSensitive(int column)
throws SQLException
{
return true; return true;
} }
@Override @Override
public boolean isSearchable(int column) throws SQLException { public boolean isSearchable(int column)
throws SQLException
{
return false; return false;
} }
@Override @Override
public boolean isCurrency(int column) throws SQLException { public boolean isCurrency(int column)
throws SQLException
{
return false; return false;
} }
@Override @Override
public int isNullable(int column) throws SQLException { public int isNullable(int column)
throws SQLException
{
return ResultSetMetaData.columnNoNulls; return ResultSetMetaData.columnNoNulls;
} }
@Override @Override
public boolean isSigned(int column) throws SQLException { public boolean isSigned(int column)
throws SQLException
{
return false; return false;
} }
@Override @Override
public int getColumnDisplaySize(int column) throws SQLException { public int getColumnDisplaySize(int column)
throws SQLException
{
return MAX_SIZE; return MAX_SIZE;
} }
@Override @Override
public String getColumnLabel(int column) throws SQLException { public String getColumnLabel(int column)
throws SQLException
{
return "RESULTS"; return "RESULTS";
} }
@Override @Override
public String getColumnName(int column) throws SQLException { public String getColumnName(int column)
throws SQLException
{
return "RESULTS"; return "RESULTS";
} }
@Override @Override
public String getSchemaName(int column) throws SQLException { public String getSchemaName(int column)
throws SQLException
{
LOGGER.log("getSchemaName(%s)", column); LOGGER.log("getSchemaName(%s)", column);
return "9"; return "9";
} }
@Override @Override
public int getPrecision(int column) throws SQLException { public int getPrecision(int column)
throws SQLException
{
return MAX_SIZE; return MAX_SIZE;
} }
@Override @Override
public int getScale(int column) throws SQLException { public int getScale(int column)
throws SQLException
{
return 0; return 0;
} }
@Override @Override
public String getTableName(int column) throws SQLException { public String getTableName(int column)
throws SQLException
{
return ""; return "";
} }
@Override @Override
public String getCatalogName(int column) throws SQLException { public String getCatalogName(int column)
throws SQLException
{
return ""; return "";
} }
@Override @Override
public int getColumnType(int column) throws SQLException { public int getColumnType(int column)
throws SQLException
{
return Types.NVARCHAR; return Types.NVARCHAR;
} }
@Override @Override
public String getColumnTypeName(int column) throws SQLException { public String getColumnTypeName(int column)
throws SQLException
{
return "String"; return "String";
} }
@Override @Override
public boolean isReadOnly(int column) throws SQLException { public boolean isReadOnly(int column)
throws SQLException
{
return true; return true;
} }
@Override @Override
public boolean isWritable(int column) throws SQLException { public boolean isWritable(int column)
throws SQLException
{
return false; return false;
} }
@Override @Override
public boolean isDefinitelyWritable(int column) throws SQLException { public boolean isDefinitelyWritable(int column)
throws SQLException
{
return false; return false;
} }
@Override @Override
public String getColumnClassName(int column) throws SQLException { public String getColumnClassName(int column)
throws SQLException
{
return "java.lang.String"; return "java.lang.String";
} }
} }

View File

@ -2,7 +2,9 @@ package io.edurt.datacap.core;
import java.sql.*; import java.sql.*;
public class RedisStatement implements Statement { public class RedisStatement
implements Statement
{
private final static Logger LOGGER = new Logger(RedisStatement.class); private final static Logger LOGGER = new Logger(RedisStatement.class);
private final RedisConnection connection; private final RedisConnection connection;
@ -12,13 +14,16 @@ public class RedisStatement implements Statement {
private boolean isClosed = false; private boolean isClosed = false;
private int fetchSize = 1; private int fetchSize = 1;
public RedisStatement(RedisConnection connection, RedisClient redisClient) { public RedisStatement(RedisConnection connection, RedisClient redisClient)
{
this.connection = connection; this.connection = connection;
this.redisClient = redisClient; this.redisClient = redisClient;
} }
@Override @Override
public ResultSet executeQuery(String sql) throws SQLException { public ResultSet executeQuery(String sql)
throws SQLException
{
LOGGER.log("executeQuery(%s)", sql); LOGGER.log("executeQuery(%s)", sql);
this.checkClosed(); this.checkClosed();
@ -27,9 +32,10 @@ public class RedisStatement implements Statement {
return new RedisResultSet(result, this); return new RedisResultSet(result, this);
} }
@Override @Override
public int executeUpdate(String sql) throws SQLException { public int executeUpdate(String sql)
throws SQLException
{
this.checkClosed(); this.checkClosed();
String[] result = this.redisClient.sendCommand(sql); String[] result = this.redisClient.sendCommand(sql);
@ -37,7 +43,9 @@ public class RedisStatement implements Statement {
} }
@Override @Override
public void close() throws SQLException { public void close()
throws SQLException
{
LOGGER.log("close()"); LOGGER.log("close()");
if (isClosed) { if (isClosed) {
LOGGER.log("Statement has been closed."); LOGGER.log("Statement has been closed.");
@ -50,70 +58,94 @@ public class RedisStatement implements Statement {
} }
@Override @Override
public int getMaxFieldSize() throws SQLException { public int getMaxFieldSize()
throws SQLException
{
this.checkClosed(); this.checkClosed();
return Integer.MAX_VALUE; return Integer.MAX_VALUE;
} }
@Override @Override
public void setMaxFieldSize(int max) throws SQLException { public void setMaxFieldSize(int max)
throws SQLException
{
this.checkClosed(); this.checkClosed();
// do nothing // do nothing
} }
@Override @Override
public int getMaxRows() throws SQLException { public int getMaxRows()
throws SQLException
{
this.checkClosed(); this.checkClosed();
return 0; return 0;
} }
@Override @Override
public void setMaxRows(int max) throws SQLException { public void setMaxRows(int max)
throws SQLException
{
this.checkClosed(); this.checkClosed();
// do nothing // do nothing
} }
@Override @Override
public void setEscapeProcessing(boolean enable) throws SQLException { public void setEscapeProcessing(boolean enable)
throws SQLException
{
this.checkClosed(); this.checkClosed();
// do nothing // do nothing
} }
@Override @Override
public int getQueryTimeout() throws SQLException { public int getQueryTimeout()
throws SQLException
{
this.checkClosed(); this.checkClosed();
return 0; return 0;
} }
@Override @Override
public void setQueryTimeout(int seconds) throws SQLException { public void setQueryTimeout(int seconds)
throws SQLException
{
LOGGER.log("setQueryTimeout.."); LOGGER.log("setQueryTimeout..");
} }
@Override @Override
public void cancel() throws SQLException { public void cancel()
throws SQLException
{
throw new SQLFeatureNotSupportedException("cancel not implemented"); throw new SQLFeatureNotSupportedException("cancel not implemented");
} }
@Override @Override
public SQLWarning getWarnings() throws SQLException { public SQLWarning getWarnings()
throws SQLException
{
LOGGER.log("getWarnings returns null"); LOGGER.log("getWarnings returns null");
return null; return null;
} }
@Override @Override
public void clearWarnings() throws SQLException { public void clearWarnings()
throws SQLException
{
this.checkClosed(); this.checkClosed();
} }
@Override @Override
public void setCursorName(String name) throws SQLException { public void setCursorName(String name)
throws SQLException
{
LOGGER.log("setCursorName not implemented"); LOGGER.log("setCursorName not implemented");
throw new SQLFeatureNotSupportedException("setCursorName not implemented"); throw new SQLFeatureNotSupportedException("setCursorName not implemented");
} }
@Override @Override
public boolean execute(String sql) throws SQLException { public boolean execute(String sql)
throws SQLException
{
this.checkClosed(); this.checkClosed();
String[] result = this.redisClient.sendCommand(sql); String[] result = this.redisClient.sendCommand(sql);
@ -123,13 +155,17 @@ public class RedisStatement implements Statement {
} }
@Override @Override
public ResultSet getResultSet() throws SQLException { public ResultSet getResultSet()
throws SQLException
{
this.checkClosed(); this.checkClosed();
return this.resultSet; return this.resultSet;
} }
@Override @Override
public int getUpdateCount() throws SQLException { public int getUpdateCount()
throws SQLException
{
this.checkClosed(); this.checkClosed();
LOGGER.log("getUpdateCount()"); LOGGER.log("getUpdateCount()");
// 原因在父类 // 原因在父类
@ -137,160 +173,212 @@ public class RedisStatement implements Statement {
} }
@Override @Override
public boolean getMoreResults() throws SQLException { public boolean getMoreResults()
throws SQLException
{
this.checkClosed(); this.checkClosed();
LOGGER.log("getMoreResults()"); LOGGER.log("getMoreResults()");
return this.getMoreResults(CLOSE_CURRENT_RESULT); return this.getMoreResults(CLOSE_CURRENT_RESULT);
} }
@Override @Override
public void setFetchDirection(int direction) throws SQLException { public void setFetchDirection(int direction)
throws SQLException
{
this.checkClosed(); this.checkClosed();
LOGGER.log("setFetchDirection not implemented"); LOGGER.log("setFetchDirection not implemented");
throw new SQLFeatureNotSupportedException("setFetchDirection not implemented"); throw new SQLFeatureNotSupportedException("setFetchDirection not implemented");
} }
@Override @Override
public int getFetchDirection() throws SQLException { public int getFetchDirection()
throws SQLException
{
this.checkClosed(); this.checkClosed();
return java.sql.ResultSet.FETCH_FORWARD; return java.sql.ResultSet.FETCH_FORWARD;
} }
@Override @Override
public void setFetchSize(int rows) throws SQLException { public void setFetchSize(int rows)
throws SQLException
{
this.checkClosed(); this.checkClosed();
this.fetchSize = rows; this.fetchSize = rows;
} }
@Override @Override
public int getFetchSize() throws SQLException { public int getFetchSize()
throws SQLException
{
this.checkClosed(); this.checkClosed();
return this.fetchSize; return this.fetchSize;
} }
@Override @Override
public int getResultSetConcurrency() throws SQLException { public int getResultSetConcurrency()
throws SQLException
{
this.checkClosed(); this.checkClosed();
return ResultSet.CONCUR_READ_ONLY; return ResultSet.CONCUR_READ_ONLY;
} }
@Override @Override
public int getResultSetType() throws SQLException { public int getResultSetType()
throws SQLException
{
this.checkClosed(); this.checkClosed();
return ResultSet.TYPE_FORWARD_ONLY; return ResultSet.TYPE_FORWARD_ONLY;
} }
@Override @Override
public void addBatch(String sql) throws SQLException { public void addBatch(String sql)
throws SQLException
{
this.checkClosed(); this.checkClosed();
LOGGER.log("addBatch not implemented"); LOGGER.log("addBatch not implemented");
throw new SQLFeatureNotSupportedException("addBatch not implemented"); throw new SQLFeatureNotSupportedException("addBatch not implemented");
} }
@Override @Override
public void clearBatch() throws SQLException { public void clearBatch()
throws SQLException
{
this.checkClosed(); this.checkClosed();
LOGGER.log("clearBatch not implemented"); LOGGER.log("clearBatch not implemented");
throw new SQLFeatureNotSupportedException("addBatch not implemented"); throw new SQLFeatureNotSupportedException("addBatch not implemented");
} }
@Override @Override
public int[] executeBatch() throws SQLException { public int[] executeBatch()
throws SQLException
{
this.checkClosed(); this.checkClosed();
LOGGER.log("executeBatch not implemented"); LOGGER.log("executeBatch not implemented");
throw new SQLFeatureNotSupportedException("executeBatch not implemented"); throw new SQLFeatureNotSupportedException("executeBatch not implemented");
} }
@Override @Override
public Connection getConnection() throws SQLException { public Connection getConnection()
throws SQLException
{
this.checkClosed(); this.checkClosed();
return this.connection; return this.connection;
} }
@Override @Override
public boolean getMoreResults(int current) throws SQLException { public boolean getMoreResults(int current)
throws SQLException
{
this.checkClosed(); this.checkClosed();
LOGGER.log("getMoreResults(%s)", current); LOGGER.log("getMoreResults(%s)", current);
return false; return false;
} }
@Override @Override
public ResultSet getGeneratedKeys() throws SQLException { public ResultSet getGeneratedKeys()
throws SQLException
{
LOGGER.log("getGeneratedKeys not implemented"); LOGGER.log("getGeneratedKeys not implemented");
throw new SQLFeatureNotSupportedException("getGeneratedKeys not implemented"); throw new SQLFeatureNotSupportedException("getGeneratedKeys not implemented");
} }
@Override @Override
public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { public int executeUpdate(String sql, int autoGeneratedKeys)
throws SQLException
{
this.executeUpdate(sql); this.executeUpdate(sql);
return 0; return 0;
} }
@Override @Override
public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { public int executeUpdate(String sql, int[] columnIndexes)
throws SQLException
{
return this.executeUpdate(sql, 0); return this.executeUpdate(sql, 0);
} }
@Override @Override
public int executeUpdate(String sql, String[] columnNames) throws SQLException { public int executeUpdate(String sql, String[] columnNames)
throws SQLException
{
return this.executeUpdate(sql, 0); return this.executeUpdate(sql, 0);
} }
@Override @Override
public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { public boolean execute(String sql, int autoGeneratedKeys)
throws SQLException
{
this.executeUpdate(sql); this.executeUpdate(sql);
return true; return true;
} }
@Override @Override
public boolean execute(String sql, int[] columnIndexes) throws SQLException { public boolean execute(String sql, int[] columnIndexes)
throws SQLException
{
return this.execute(sql, 0); return this.execute(sql, 0);
} }
@Override @Override
public boolean execute(String sql, String[] columnNames) throws SQLException { public boolean execute(String sql, String[] columnNames)
throws SQLException
{
return this.execute(sql, 0); return this.execute(sql, 0);
} }
@Override @Override
public int getResultSetHoldability() throws SQLException { public int getResultSetHoldability()
throws SQLException
{
this.checkClosed(); this.checkClosed();
return ResultSet.HOLD_CURSORS_OVER_COMMIT; return ResultSet.HOLD_CURSORS_OVER_COMMIT;
} }
@Override @Override
public boolean isClosed() throws SQLException { public boolean isClosed()
throws SQLException
{
LOGGER.log("Statement isClosed = %s", isClosed); LOGGER.log("Statement isClosed = %s", isClosed);
return this.isClosed; return this.isClosed;
} }
@Override @Override
public void setPoolable(boolean poolable) throws SQLException { public void setPoolable(boolean poolable)
throws SQLException
{
LOGGER.log("setPoolable not implemented"); LOGGER.log("setPoolable not implemented");
throw new SQLFeatureNotSupportedException("setPoolable not implemented"); throw new SQLFeatureNotSupportedException("setPoolable not implemented");
} }
@Override @Override
public boolean isPoolable() throws SQLException { public boolean isPoolable()
throws SQLException
{
this.checkClosed(); this.checkClosed();
return false; return false;
} }
@Override @Override
public void closeOnCompletion() throws SQLException { public void closeOnCompletion()
throws SQLException
{
this.checkClosed(); this.checkClosed();
LOGGER.log("closeOnCompletion not implemented"); LOGGER.log("closeOnCompletion not implemented");
throw new SQLFeatureNotSupportedException("closeOnCompletion not implemented"); throw new SQLFeatureNotSupportedException("closeOnCompletion not implemented");
} }
@Override @Override
public boolean isCloseOnCompletion() throws SQLException { public boolean isCloseOnCompletion()
throws SQLException
{
this.checkClosed(); this.checkClosed();
LOGGER.log("isCloseOnCompletion not implemented"); LOGGER.log("isCloseOnCompletion not implemented");
return false; return false;
} }
private void checkClosed() throws SQLException { private void checkClosed()
throws SQLException
{
if (isClosed()) { if (isClosed()) {
LOGGER.log("Statement is closed."); LOGGER.log("Statement is closed.");
throw new SQLException("Statement is closed."); throw new SQLException("Statement is closed.");
@ -298,17 +386,22 @@ public class RedisStatement implements Statement {
} }
@Override @Override
public <T> T unwrap(Class<T> iface) throws SQLException { public <T> T unwrap(Class<T> iface)
throws SQLException
{
try { try {
return iface.cast(this); return iface.cast(this);
} catch (ClassCastException cce) { }
catch (ClassCastException cce) {
LOGGER.log("Unable to unwrap to %s", iface); LOGGER.log("Unable to unwrap to %s", iface);
throw new SQLException("Unable to unwrap to " + iface); throw new SQLException("Unable to unwrap to " + iface);
} }
} }
@Override @Override
public boolean isWrapperFor(Class<?> iface) throws SQLException { public boolean isWrapperFor(Class<?> iface)
throws SQLException
{
return iface.isInstance(this); return iface.isInstance(this);
} }
} }

View File

@ -3,14 +3,16 @@ package io.edurt.datacap.core;
import lombok.Data; import lombok.Data;
@Data @Data
public class ServerVersion { public class ServerVersion
{
private String origin; private String origin;
private Integer major; private Integer major;
private Integer minor; private Integer minor;
private Integer patch; private Integer patch;
public ServerVersion(String origin) { public ServerVersion(String origin)
{
this.origin = origin; this.origin = origin;
String[] arr = origin.split("\\."); String[] arr = origin.split("\\.");
@ -19,9 +21,11 @@ public class ServerVersion {
int v = Utils.isNumber(str) ? Integer.parseInt(str) : 0; int v = Utils.isNumber(str) ? Integer.parseInt(str) : 0;
if (i == 0) { if (i == 0) {
this.major = v; this.major = v;
} else if (i == 1) { }
else if (i == 1) {
minor = v; minor = v;
} else if (i == 2) { }
else if (i == 2) {
patch = v; patch = v;
} }
} }

View File

@ -5,8 +5,10 @@ import java.io.StringReader;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class Utils { public class Utils
public static boolean isNumber(String str) { {
public static boolean isNumber(String str)
{
if (str == null || str.length() == 0) { if (str == null || str.length() == 0) {
return false; return false;
} }
@ -19,7 +21,8 @@ public class Utils {
return true; return true;
} }
public static <T> List<T> toList(T[] arr) { public static <T> List<T> toList(T[] arr)
{
if (arr == null) { if (arr == null) {
return null; return null;
} }
@ -27,7 +30,8 @@ public class Utils {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
public static Op parseSql(String rawSql) { public static Op parseSql(String rawSql)
{
// for IDEA database tool only // for IDEA database tool only
if (rawSql.contains("SELECT 'keep alive'")) { if (rawSql.contains("SELECT 'keep alive'")) {
return new Op(rawSql, null, "PING", new String[0]); return new Op(rawSql, null, "PING", new String[0]);
@ -43,7 +47,8 @@ public class Utils {
lines.forEach(line -> { lines.forEach(line -> {
if (line.startsWith("--")) { if (line.startsWith("--")) {
hintLines.add(line); hintLines.add(line);
} else { }
else {
sqlLines.add(line); sqlLines.add(line);
} }
}); });
@ -57,7 +62,6 @@ public class Utils {
return new Hint(HintKey.fromString(arr[0]), arr[1]); return new Hint(HintKey.fromString(arr[0]), arr[1]);
}).collect(Collectors.toList()); }).collect(Collectors.toList());
// sql to execute // sql to execute
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sqlLines.forEach(sb::append); sqlLines.forEach(sb::append);
@ -70,13 +74,15 @@ public class Utils {
if (arr.length == 1) { if (arr.length == 1) {
return new Op(rawSql, hints, commandString, new String[0]); return new Op(rawSql, hints, commandString, new String[0]);
} else { }
else {
String[] commandParams = Arrays.copyOfRange(arr, 1, arr.length); String[] commandParams = Arrays.copyOfRange(arr, 1, arr.length);
return new Op(rawSql, hints, commandString, commandParams); return new Op(rawSql, hints, commandString, commandParams);
} }
} }
public static Map<String, String> parseQueryStringToMap(String queryString) { public static Map<String, String> parseQueryStringToMap(String queryString)
{
String[] params = queryString.split("&"); String[] params = queryString.split("&");
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
for (String param : params) { for (String param : params) {

View File

@ -1,5 +1,6 @@
package io.edurt.datacap.driver; package io.edurt.datacap.driver;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.edurt.datacap.core.Hint; import io.edurt.datacap.core.Hint;
import io.edurt.datacap.core.Logger; import io.edurt.datacap.core.Logger;
import io.edurt.datacap.core.Op; import io.edurt.datacap.core.Op;
@ -14,26 +15,33 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.stream.Stream; import java.util.stream.Stream;
public abstract class AbstractRedisClient implements RedisClient @SuppressFBWarnings(value = {"BC_BAD_CAST_TO_ABSTRACT_COLLECTION"},
justification = "I prefer to suppress these FindBugs warnings")
public abstract class AbstractRedisClient
implements RedisClient
{ {
public static final Logger LOGGER = new Logger(AbstractRedisClient.class); public static final Logger LOGGER = new Logger(AbstractRedisClient.class);
@Override @Override
public String[] sendCommand(String sql) throws SQLException { public String[] sendCommand(String sql)
throws SQLException
{
try { try {
Op op = Utils.parseSql(sql); Op op = Utils.parseSql(sql);
Object result = this.sendCommand(op); Object result = this.sendCommand(op);
return this.decodeResult(sql, result, op.getHints()); return this.decodeResult(sql, result, op.getHints());
} catch (Throwable e) { }
catch (Throwable e) {
throw new SQLException(e); throw new SQLException(e);
} }
} }
protected abstract Object sendCommand(Op op); protected abstract Object sendCommand(Op op);
protected Protocol.Command convertCommand(String commandString) { protected Protocol.Command convertCommand(String commandString)
{
return Arrays.stream(Protocol.Command.values()) return Arrays.stream(Protocol.Command.values())
.filter(t -> { .filter(t -> {
String string = t.toString(); String string = t.toString();
@ -45,7 +53,6 @@ public abstract class AbstractRedisClient implements RedisClient
)); ));
} }
/** /**
* hint: * hint:
* -- decoder:jdk * -- decoder:jdk
@ -56,22 +63,24 @@ public abstract class AbstractRedisClient implements RedisClient
* @param hints * @param hints
* @return * @return
*/ */
protected String[] decodeResult(String sql, Object originResult, List<Hint> hints) { protected String[] decodeResult(String sql, Object originResult, List<Hint> hints)
{
String[] decodedResult; String[] decodedResult;
if (originResult == null) { if (originResult == null) {
decodedResult = new String[]{null}; decodedResult = new String[] {null};
} else if (originResult.getClass().isArray()) { }
else if (originResult.getClass().isArray()) {
String decoded = SafeEncoder.encode((byte[]) originResult); String decoded = SafeEncoder.encode((byte[]) originResult);
decodedResult = Stream.of(decoded) decodedResult = Stream.of(decoded)
.toArray(String[]::new); .toArray(String[]::new);
}
} else if (originResult instanceof Collection) { else if (originResult instanceof Collection) {
List<?> list = (List<?>) originResult; List<?> list = (List<?>) originResult;
decodedResult = list.stream() decodedResult = list.stream()
.map(t -> SafeEncoder.encode((byte[]) t)) .map(t -> SafeEncoder.encode((byte[]) t))
.toArray(String[]::new); .toArray(String[]::new);
}
} else { else {
LOGGER.log("cannot decode result. originResult = %s", originResult); LOGGER.log("cannot decode result. originResult = %s", originResult);
decodedResult = Stream.of(originResult.toString()) decodedResult = Stream.of(originResult.toString())
.toArray(String[]::new); .toArray(String[]::new);

View File

@ -12,11 +12,14 @@ import java.sql.SQLException;
import java.util.List; import java.util.List;
@RequiredArgsConstructor @RequiredArgsConstructor
public class JedisRedisClusterClient extends AbstractRedisClient { public class JedisRedisClusterClient
extends AbstractRedisClient
{
private final JedisCluster jedisCluster; private final JedisCluster jedisCluster;
@Override @Override
protected Object sendCommand(Op op) { protected Object sendCommand(Op op)
{
String rawSql = op.getOriginSql(); String rawSql = op.getOriginSql();
String commandString = op.getCommand(); String commandString = op.getCommand();
String[] params = op.getParams(); String[] params = op.getParams();
@ -34,23 +37,28 @@ public class JedisRedisClusterClient extends AbstractRedisClient {
Object result; Object result;
if (params == null || params.length == 0) { if (params == null || params.length == 0) {
result = this.jedisCluster.sendCommand(sampleKey, command); result = this.jedisCluster.sendCommand(sampleKey, command);
} else { }
else {
result = this.jedisCluster.sendCommand(sampleKey, command, params); result = this.jedisCluster.sendCommand(sampleKey, command, params);
} }
return result; return result;
} catch (Throwable e) { }
catch (Throwable e) {
LOGGER.log("command `%s` cannot execute.", rawSql); LOGGER.log("command `%s` cannot execute.", rawSql);
throw new RuntimeException(String.format("command `%s` cannot execute.", rawSql)); throw new RuntimeException(String.format("command `%s` cannot execute.", rawSql));
} }
} }
@Override @Override
public void select(int dbIndex) throws SQLException { public void select(int dbIndex)
throws SQLException
{
throw new SQLException("Redis Cluster does not support this operation"); throw new SQLException("Redis Cluster does not support this operation");
} }
@Override @Override
public void close() { public void close()
{
this.jedisCluster.close(); this.jedisCluster.close();
} }
} }

View File

@ -12,7 +12,9 @@ import java.net.URISyntaxException;
import java.sql.*; import java.sql.*;
import java.util.Properties; import java.util.Properties;
public class RedisClusterDriver implements Driver { public class RedisClusterDriver
implements Driver
{
private final static Logger LOGGER = new Logger(RedisDriver.class); private final static Logger LOGGER = new Logger(RedisDriver.class);
private static final String REDIS_CLUSTER_JDBC_PREFIX = "jdbc:redis-cluster:"; private static final String REDIS_CLUSTER_JDBC_PREFIX = "jdbc:redis-cluster:";
@ -20,14 +22,17 @@ public class RedisClusterDriver implements Driver {
static { static {
try { try {
DriverManager.registerDriver(new RedisClusterDriver()); DriverManager.registerDriver(new RedisClusterDriver());
} catch (Exception e) { }
catch (Exception e) {
LOGGER.log("Can't register driver!"); LOGGER.log("Can't register driver!");
throw new RuntimeException("Can't register driver!", e); throw new RuntimeException("Can't register driver!", e);
} }
} }
@Override @Override
public Connection connect(String url, Properties info) throws SQLException { public Connection connect(String url, Properties info)
throws SQLException
{
if (!this.acceptsURL(url)) { if (!this.acceptsURL(url)) {
LOGGER.log("wrong url. url is %s", url); LOGGER.log("wrong url. url is %s", url);
return null; return null;
@ -55,36 +60,47 @@ public class RedisClusterDriver implements Driver {
} }
@Override @Override
public boolean acceptsURL(String url) throws SQLException { public boolean acceptsURL(String url)
throws SQLException
{
return url.toLowerCase().startsWith(REDIS_CLUSTER_JDBC_PREFIX); return url.toLowerCase().startsWith(REDIS_CLUSTER_JDBC_PREFIX);
} }
@Override @Override
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
throws SQLException
{
return new DriverPropertyInfo[0]; return new DriverPropertyInfo[0];
} }
@Override @Override
public int getMajorVersion() { public int getMajorVersion()
{
return 0; return 0;
} }
@Override @Override
public int getMinorVersion() { public int getMinorVersion()
{
return 0; return 0;
} }
@Override @Override
public boolean jdbcCompliant() { public boolean jdbcCompliant()
{
return false; return false;
} }
@Override @Override
public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException { public java.util.logging.Logger getParentLogger()
throws SQLFeatureNotSupportedException
{
return null; return null;
} }
public static void main(String[] args) throws URISyntaxException { public static void main(String[] args)
throws URISyntaxException
{
URI uri = new URI("cluster:///?hosts=localhost:3306"); URI uri = new URI("cluster:///?hosts=localhost:3306");
System.out.println(uri.getQuery()); System.out.println(uri.getQuery());
} }

View File

@ -7,13 +7,15 @@ import java.util.Properties;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
public class BaseConnectionInfo { public class BaseConnectionInfo
{
protected String username; protected String username;
protected String password; protected String password;
protected boolean ssl; protected boolean ssl;
protected int timeout; protected int timeout;
public BaseConnectionInfo(Properties info) { public BaseConnectionInfo(Properties info)
{
String username = info.getProperty("user"); String username = info.getProperty("user");
String password = info.getProperty("password"); String password = info.getProperty("password");
String sslString = info.getProperty("ssl"); String sslString = info.getProperty("ssl");

View File

@ -18,13 +18,16 @@ import java.util.stream.Collectors;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class RedisClusterConnectionInfo extends BaseConnectionInfo { public class RedisClusterConnectionInfo
extends BaseConnectionInfo
{
public static final Logger LOGGER = new Logger(RedisClusterConnectionInfo.class); public static final Logger LOGGER = new Logger(RedisClusterConnectionInfo.class);
private Set<HostAndPort> nodes; private Set<HostAndPort> nodes;
private int maxAttempts; private int maxAttempts;
public RedisClusterConnectionInfo(String rawUrl, Properties info) { public RedisClusterConnectionInfo(String rawUrl, Properties info)
{
super((info)); super((info));
try { try {
URI uri = new URI(rawUrl); URI uri = new URI(rawUrl);
@ -43,7 +46,8 @@ public class RedisClusterConnectionInfo extends BaseConnectionInfo {
}).collect(Collectors.toSet()); }).collect(Collectors.toSet());
this.maxAttempts = maxAttempts; this.maxAttempts = maxAttempts;
} catch (Exception e) { }
catch (Exception e) {
LOGGER.log("Cannot parse JDBC URL %s", rawUrl); LOGGER.log("Cannot parse JDBC URL %s", rawUrl);
throw new RuntimeException("Cannot parse JDBC URL: " + rawUrl, e); throw new RuntimeException("Cannot parse JDBC URL: " + rawUrl, e);
} }

View File

@ -8,14 +8,17 @@ import java.util.Properties;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class RedisConnectionInfo extends BaseConnectionInfo { public class RedisConnectionInfo
extends BaseConnectionInfo
{
private final static Logger LOGGER = new Logger(RedisConnectionInfo.class); private final static Logger LOGGER = new Logger(RedisConnectionInfo.class);
private String host; private String host;
private int port; private int port;
private int dbIndex; private int dbIndex;
public RedisConnectionInfo(String rawUrl, Properties info) { public RedisConnectionInfo(String rawUrl, Properties info)
{
super(info); super(info);
try { try {
URI uri = new URI(rawUrl); URI uri = new URI(rawUrl);
@ -32,8 +35,8 @@ public class RedisConnectionInfo extends BaseConnectionInfo {
this.host = host; this.host = host;
this.port = port; this.port = port;
this.dbIndex = dbIndex; this.dbIndex = dbIndex;
}
} catch (Exception e) { catch (Exception e) {
LOGGER.log("Cannot parse JDBC URL %s", rawUrl); LOGGER.log("Cannot parse JDBC URL %s", rawUrl);
throw new RuntimeException("Cannot parse JDBC URL: " + rawUrl, e); throw new RuntimeException("Cannot parse JDBC URL: " + rawUrl, e);
} }

View File

@ -6,17 +6,21 @@ import io.edurt.datacap.core.Op;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.Protocol; import redis.clients.jedis.Protocol;
public class JedisRedisClient extends AbstractRedisClient { public class JedisRedisClient
extends AbstractRedisClient
{
public static final Logger LOGGER = new Logger(JedisRedisClient.class); public static final Logger LOGGER = new Logger(JedisRedisClient.class);
private final Jedis jedis; private final Jedis jedis;
public JedisRedisClient(Jedis jedis) { public JedisRedisClient(Jedis jedis)
{
this.jedis = jedis; this.jedis = jedis;
} }
@Override @Override
protected synchronized Object sendCommand(Op op) { protected synchronized Object sendCommand(Op op)
{
String rawSql = op.getOriginSql(); String rawSql = op.getOriginSql();
String commandString = op.getCommand(); String commandString = op.getCommand();
String[] params = op.getParams(); String[] params = op.getParams();
@ -29,23 +33,27 @@ public class JedisRedisClient extends AbstractRedisClient {
Object result; Object result;
if (params == null || params.length == 0) { if (params == null || params.length == 0) {
result = this.jedis.sendCommand(command); result = this.jedis.sendCommand(command);
} else { }
else {
result = this.jedis.sendCommand(command, params); result = this.jedis.sendCommand(command, params);
} }
return result; return result;
} catch (Throwable e) { }
catch (Throwable e) {
LOGGER.log("command on db %s `%s` cannot execute.", db, rawSql); LOGGER.log("command on db %s `%s` cannot execute.", db, rawSql);
throw new RuntimeException(String.format("command on db %s `%s` cannot execute.", db, rawSql)); throw new RuntimeException(String.format("command on db %s `%s` cannot execute.", db, rawSql));
} }
} }
@Override @Override
public synchronized void select(int dbIndex) { public synchronized void select(int dbIndex)
{
this.jedis.select(dbIndex); this.jedis.select(dbIndex);
} }
@Override @Override
public synchronized void close() { public synchronized void close()
{
LOGGER.log("close()"); LOGGER.log("close()");
this.jedis.close(); this.jedis.close();
} }

View File

@ -8,7 +8,9 @@ import redis.clients.jedis.Jedis;
import java.sql.*; import java.sql.*;
import java.util.Properties; import java.util.Properties;
public class RedisDriver implements Driver { public class RedisDriver
implements Driver
{
private final static Logger LOGGER = new Logger(RedisDriver.class); private final static Logger LOGGER = new Logger(RedisDriver.class);
private static final String REDIS_JDBC_PREFIX = "jdbc:redis:"; private static final String REDIS_JDBC_PREFIX = "jdbc:redis:";
@ -16,14 +18,17 @@ public class RedisDriver implements Driver {
static { static {
try { try {
DriverManager.registerDriver(new RedisDriver()); DriverManager.registerDriver(new RedisDriver());
} catch (Exception e) { }
catch (Exception e) {
LOGGER.log("Can't register driver!"); LOGGER.log("Can't register driver!");
throw new RuntimeException("Can't register driver!", e); throw new RuntimeException("Can't register driver!", e);
} }
} }
@Override @Override
public Connection connect(String url, Properties info) throws SQLException { public Connection connect(String url, Properties info)
throws SQLException
{
if (!this.acceptsURL(url)) { if (!this.acceptsURL(url)) {
LOGGER.log("wrong url. url is %s", url); LOGGER.log("wrong url. url is %s", url);
return null; return null;
@ -49,7 +54,8 @@ public class RedisDriver implements Driver {
if (username != null) { if (username != null) {
jedis.auth(username, password); jedis.auth(username, password);
} else if (password != null) { }
else if (password != null) {
jedis.auth(password); jedis.auth(password);
} }
if (dbIndex != 0) { if (dbIndex != 0) {
@ -60,39 +66,49 @@ public class RedisDriver implements Driver {
// } // }
return new RedisConnection(new JedisRedisClient(jedis), dbIndex + "", info); return new RedisConnection(new JedisRedisClient(jedis), dbIndex + "", info);
} catch (Exception e) { }
catch (Exception e) {
LOGGER.log("Cannot init RedisConnection %s", e); LOGGER.log("Cannot init RedisConnection %s", e);
throw new SQLException("Cannot init RedisConnection", e); throw new SQLException("Cannot init RedisConnection", e);
} }
} }
@Override @Override
public boolean acceptsURL(String url) throws SQLException { public boolean acceptsURL(String url)
throws SQLException
{
return url.toLowerCase().startsWith(REDIS_JDBC_PREFIX); return url.toLowerCase().startsWith(REDIS_JDBC_PREFIX);
} }
@Override @Override
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
throws SQLException
{
return new DriverPropertyInfo[0]; return new DriverPropertyInfo[0];
} }
@Override @Override
public int getMajorVersion() { public int getMajorVersion()
{
return 1; return 1;
} }
@Override @Override
public int getMinorVersion() { public int getMinorVersion()
{
return 0; return 0;
} }
@Override @Override
public boolean jdbcCompliant() { public boolean jdbcCompliant()
{
return false; return false;
} }
@Override @Override
public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException { public java.util.logging.Logger getParentLogger()
throws SQLFeatureNotSupportedException
{
// ref: com.mysql.cj.jdbc.NonRegisteringDriver.getParentLogger // ref: com.mysql.cj.jdbc.NonRegisteringDriver.getParentLogger
LOGGER.log("getParentLogger not implemented"); LOGGER.log("getParentLogger not implemented");
throw new SQLFeatureNotSupportedException("getParentLogger not implemented"); throw new SQLFeatureNotSupportedException("getParentLogger not implemented");

View File

@ -1,5 +1,6 @@
package io.edurt.datacap; package io.edurt.datacap;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.edurt.datacap.core.Logger; import io.edurt.datacap.core.Logger;
import io.edurt.datacap.core.RedisStatement; import io.edurt.datacap.core.RedisStatement;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -10,10 +11,15 @@ import lombok.NoArgsConstructor;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.*; import java.sql.*;
public class RedisTest { @SuppressFBWarnings(value = {"OBL_UNSATISFIED_OBLIGATION", "SQL_BAD_RESULTSET_ACCESS"},
justification = "I prefer to suppress these FindBugs warnings")
public class RedisTest
{
private final static Logger LOGGER = new Logger(RedisStatement.class); private final static Logger LOGGER = new Logger(RedisStatement.class);
public static void main(String[] args) throws SQLException, ClassNotFoundException { public static void main(String[] args)
throws SQLException, ClassNotFoundException
{
Class.forName("com.itmuch.redis.jdbc.redis.RedisDriver"); Class.forName("com.itmuch.redis.jdbc.redis.RedisDriver");
Connection connection = DriverManager.getConnection("jdbc:redis://localhost:6379/0"); Connection connection = DriverManager.getConnection("jdbc:redis://localhost:6379/0");
@ -73,10 +79,10 @@ public class RedisTest {
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
class User { class User
{
private String name; private String name;
private Short age; private Short age;
private String email; private String email;
private BigDecimal money; private BigDecimal money;
} }

View File

@ -14,6 +14,7 @@
<module>core/datacap-server</module> <module>core/datacap-server</module>
<module>lib/datacap-http</module> <module>lib/datacap-http</module>
<module>lib/datacap-logger</module> <module>lib/datacap-logger</module>
<module>driver/datacap-driver-redis</module>
<module>plugin/datacap-native-alioss</module> <module>plugin/datacap-native-alioss</module>
<module>plugin/datacap-native-zookeeper</module> <module>plugin/datacap-native-zookeeper</module>
<module>plugin/datacap-native-redis</module> <module>plugin/datacap-native-redis</module>
@ -49,7 +50,6 @@
<module>plugin/datacap-jdbc-sqlserver</module> <module>plugin/datacap-jdbc-sqlserver</module>
<module>plugin/datacap-jdbc-tdengine</module> <module>plugin/datacap-jdbc-tdengine</module>
<module>plugin/datacap-jdbc-trino</module> <module>plugin/datacap-jdbc-trino</module>
<module>driver/datacap-driver-redis</module>
</modules> </modules>
<name>DataCap</name> <name>DataCap</name>