diff --git a/agent/pom.xml b/agent/pom.xml
index e68db91..a25dd04 100644
--- a/agent/pom.xml
+++ b/agent/pom.xml
@@ -76,13 +76,26 @@
test
-
+
+
org.junit.jupiter
junit-jupiter-engine
- 5.4.0
+ 5.9.0
test
+
+
+
+
+ org.junit.platform
+ junit-platform-suite-engine
+ 1.9.0
+ test
+
+
+
+
\ No newline at end of file
diff --git a/agent/src/main/java/com/fanruan/AgentStarter.java b/agent/src/main/java/com/fanruan/AgentStarter.java
index e68b393..f65d283 100644
--- a/agent/src/main/java/com/fanruan/AgentStarter.java
+++ b/agent/src/main/java/com/fanruan/AgentStarter.java
@@ -16,6 +16,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
+import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
@@ -37,7 +38,6 @@ public class AgentStarter {
dispatcherImpl = new DispatcherImpl();
try {
createSocket(DBs);
-
} catch (Exception e) {
e.printStackTrace();
}
@@ -94,6 +94,13 @@ public class AgentStarter {
}
}
+ public void shutDown(){
+ List sockets = DispatcherImpl.CACHE.getSockets();
+ for(Socket socket : sockets){
+ socket.close();
+ }
+ }
+
private void configDefaultSocket(Socket socket) throws IOException {
socket.on(Socket.EVENT_CONNECT, objects -> {
logger.info("default-socket connected!");
diff --git a/agent/src/main/java/com/fanruan/agent/jdbc/AgentArray.java b/agent/src/main/java/com/fanruan/agent/jdbc/AgentArray.java
new file mode 100644
index 0000000..c8af6c6
--- /dev/null
+++ b/agent/src/main/java/com/fanruan/agent/jdbc/AgentArray.java
@@ -0,0 +1,73 @@
+package com.fanruan.agent.jdbc;
+
+import java.sql.Array;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Map;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/31 16:52
+ */
+public class AgentArray implements Array {
+ Array array;
+
+ AgentArray(Array array){
+ this.array = array;
+ }
+
+ @Override
+ public String getBaseTypeName() throws SQLException {
+ return array.getBaseTypeName();
+ }
+
+ @Override
+ public int getBaseType() throws SQLException {
+ return array.getBaseType();
+ }
+
+ @Override
+ public Object getArray() throws SQLException {
+ return array.getArray();
+ }
+
+ @Override
+ public Object getArray(Map> map) throws SQLException {
+ return array.getArray(map);
+ }
+
+ @Override
+ public Object getArray(long index, int count) throws SQLException {
+ return array.getArray(index, count);
+ }
+
+ @Override
+ public Object getArray(long index, int count, Map> map) throws SQLException {
+ return array.getArray(index, count, map);
+ }
+
+ @Override
+ public ResultSet getResultSet() throws SQLException {
+ return array.getResultSet();
+ }
+
+ @Override
+ public ResultSet getResultSet(Map> map) throws SQLException {
+ return array.getResultSet(map);
+ }
+
+ @Override
+ public ResultSet getResultSet(long index, int count) throws SQLException {
+ return array.getResultSet(index, count);
+ }
+
+ @Override
+ public ResultSet getResultSet(long index, int count, Map> map) throws SQLException {
+ return array.getResultSet(index, count, map);
+ }
+
+ @Override
+ public void free() throws SQLException {
+ array.free();
+ }
+}
diff --git a/agent/src/main/java/com/fanruan/agent/jdbc/AgentBlob.java b/agent/src/main/java/com/fanruan/agent/jdbc/AgentBlob.java
new file mode 100644
index 0000000..16f2b78
--- /dev/null
+++ b/agent/src/main/java/com/fanruan/agent/jdbc/AgentBlob.java
@@ -0,0 +1,73 @@
+package com.fanruan.agent.jdbc;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.sql.Blob;
+import java.sql.SQLException;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/29 20:33
+ */
+public class AgentBlob implements Blob {
+ private Blob blob;
+
+ AgentBlob(Blob blob){
+ this.blob = blob;
+ }
+
+ @Override
+ public long length() throws SQLException {
+ return blob.length();
+ }
+
+ @Override
+ public byte[] getBytes(long pos, int length) throws SQLException {
+ return blob.getBytes(pos, length);
+ }
+
+ @Override
+ public InputStream getBinaryStream() throws SQLException {
+ return blob.getBinaryStream();
+ }
+
+ @Override
+ public long position(byte[] pattern, long start) throws SQLException {
+ return blob.position(pattern, start);
+ }
+
+ @Override
+ public long position(Blob pattern, long start) throws SQLException {
+ return blob.position(pattern, start);
+ }
+
+ @Override
+ public int setBytes(long pos, byte[] bytes) throws SQLException {
+ return blob.setBytes(pos, bytes);
+ }
+
+ @Override
+ public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException {
+ return blob.setBytes(pos, bytes, offset, len);
+ }
+
+ @Override
+ public OutputStream setBinaryStream(long pos) throws SQLException {
+ return blob.setBinaryStream(pos);
+ }
+
+ @Override
+ public void truncate(long len) throws SQLException {
+ blob.truncate(len);
+ }
+
+ @Override
+ public void free() throws SQLException {
+ blob.free();
+ }
+
+ @Override
+ public InputStream getBinaryStream(long pos, long length) throws SQLException {
+ return blob.getBinaryStream(pos, length);
+ }
+}
diff --git a/agent/src/main/java/com/fanruan/agent/jdbc/AgentClob.java b/agent/src/main/java/com/fanruan/agent/jdbc/AgentClob.java
new file mode 100644
index 0000000..604bd74
--- /dev/null
+++ b/agent/src/main/java/com/fanruan/agent/jdbc/AgentClob.java
@@ -0,0 +1,85 @@
+package com.fanruan.agent.jdbc;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.sql.Clob;
+import java.sql.SQLException;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/29 20:34
+ */
+public class AgentClob implements Clob {
+ private Clob clob;
+
+ AgentClob(Clob clob){
+ this.clob = clob;
+ }
+
+ @Override
+ public long length() throws SQLException {
+ return clob.length();
+ }
+
+ @Override
+ public String getSubString(long pos, int length) throws SQLException {
+ return clob.getSubString(pos, length);
+ }
+
+ @Override
+ public Reader getCharacterStream() throws SQLException {
+ return clob.getCharacterStream();
+ }
+
+ @Override
+ public InputStream getAsciiStream() throws SQLException {
+ return clob.getAsciiStream();
+ }
+
+ @Override
+ public long position(String searchstr, long start) throws SQLException {
+ return clob.position(searchstr, start);
+ }
+
+ @Override
+ public long position(Clob searchstr, long start) throws SQLException {
+ return clob.position(searchstr, start);
+ }
+
+ @Override
+ public int setString(long pos, String str) throws SQLException {
+ return clob.setString(pos, str);
+ }
+
+ @Override
+ public int setString(long pos, String str, int offset, int len) throws SQLException {
+ return clob.setString(pos, str, offset, len);
+ }
+
+ @Override
+ public OutputStream setAsciiStream(long pos) throws SQLException {
+ return clob.setAsciiStream(pos);
+ }
+
+ @Override
+ public Writer setCharacterStream(long pos) throws SQLException {
+ return clob.setCharacterStream(pos);
+ }
+
+ @Override
+ public void truncate(long len) throws SQLException {
+ clob.truncate(len);
+ }
+
+ @Override
+ public void free() throws SQLException {
+ clob.free();
+ }
+
+ @Override
+ public Reader getCharacterStream(long pos, long length) throws SQLException {
+ return clob.getCharacterStream(pos, length);
+ }
+}
diff --git a/agent/src/main/java/com/fanruan/agent/jdbc/AgentDataBaseMetaData.java b/agent/src/main/java/com/fanruan/agent/jdbc/AgentDataBaseMetaData.java
new file mode 100644
index 0000000..d9ff58b
--- /dev/null
+++ b/agent/src/main/java/com/fanruan/agent/jdbc/AgentDataBaseMetaData.java
@@ -0,0 +1,895 @@
+package com.fanruan.agent.jdbc;
+
+import java.sql.*;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/25 11:22
+ */
+public class AgentDataBaseMetaData implements DatabaseMetaData {
+ DatabaseMetaData metaData;
+
+ public AgentDataBaseMetaData(DatabaseMetaData metaData){
+ this.metaData = metaData;
+ }
+
+ @Override
+ public boolean allProceduresAreCallable() throws SQLException {
+ return metaData.allProceduresAreCallable();
+ }
+
+ @Override
+ public boolean allTablesAreSelectable() throws SQLException {
+ return metaData.allTablesAreSelectable();
+ }
+
+ @Override
+ public String getURL() throws SQLException {
+ return metaData.getURL();
+ }
+
+ @Override
+ public String getUserName() throws SQLException {
+ return metaData.getUserName();
+ }
+
+ @Override
+ public boolean isReadOnly() throws SQLException {
+ return metaData.isReadOnly();
+ }
+
+ @Override
+ public boolean nullsAreSortedHigh() throws SQLException {
+ return metaData.nullsAreSortedHigh();
+ }
+
+ @Override
+ public boolean nullsAreSortedLow() throws SQLException {
+ return metaData.nullsAreSortedLow();
+ }
+
+ @Override
+ public boolean nullsAreSortedAtStart() throws SQLException {
+ return metaData.nullsAreSortedAtStart();
+ }
+
+ @Override
+ public boolean nullsAreSortedAtEnd() throws SQLException {
+ return metaData.nullsAreSortedAtStart();
+ }
+
+ @Override
+ public String getDatabaseProductName() throws SQLException {
+ return metaData.getDatabaseProductName();
+ }
+
+ @Override
+ public String getDatabaseProductVersion() throws SQLException {
+ return metaData.getDatabaseProductVersion();
+ }
+
+ @Override
+ public String getDriverName() throws SQLException {
+ return metaData.getDriverName();
+ }
+
+ @Override
+ public String getDriverVersion() throws SQLException {
+ return metaData.getDriverVersion();
+ }
+
+ @Override
+ public int getDriverMajorVersion() {
+ return metaData.getDriverMajorVersion();
+ }
+
+ @Override
+ public int getDriverMinorVersion() {
+ return metaData.getDriverMinorVersion();
+ }
+
+ @Override
+ public boolean usesLocalFiles() throws SQLException {
+ return metaData.usesLocalFiles();
+ }
+
+ @Override
+ public boolean usesLocalFilePerTable() throws SQLException {
+ return metaData.usesLocalFilePerTable();
+ }
+
+ @Override
+ public boolean supportsMixedCaseIdentifiers() throws SQLException {
+ return metaData.supportsMixedCaseIdentifiers();
+ }
+
+ @Override
+ public boolean storesUpperCaseIdentifiers() throws SQLException {
+ return metaData.storesUpperCaseIdentifiers();
+ }
+
+ @Override
+ public boolean storesLowerCaseIdentifiers() throws SQLException {
+ return metaData.storesLowerCaseIdentifiers();
+ }
+
+ @Override
+ public boolean storesMixedCaseIdentifiers() throws SQLException {
+ return metaData.supportsMixedCaseIdentifiers();
+ }
+
+ @Override
+ public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+ return metaData.supportsMixedCaseQuotedIdentifiers();
+ }
+
+ @Override
+ public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+ return metaData.storesUpperCaseQuotedIdentifiers();
+ }
+
+ @Override
+ public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+ return metaData.storesLowerCaseQuotedIdentifiers();
+ }
+
+ @Override
+ public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+ return metaData.supportsMixedCaseQuotedIdentifiers();
+ }
+
+ @Override
+ public String getIdentifierQuoteString() throws SQLException {
+ return metaData.getIdentifierQuoteString();
+ }
+
+ @Override
+ public String getSQLKeywords() throws SQLException {
+ return metaData.getSQLKeywords();
+ }
+
+ @Override
+ public String getNumericFunctions() throws SQLException {
+ return metaData.getNumericFunctions();
+ }
+
+ @Override
+ public String getStringFunctions() throws SQLException {
+ return metaData.getStringFunctions();
+ }
+
+ @Override
+ public String getSystemFunctions() throws SQLException {
+ return metaData.getSystemFunctions();
+ }
+
+ @Override
+ public String getTimeDateFunctions() throws SQLException {
+ return metaData.getTimeDateFunctions();
+ }
+
+ @Override
+ public String getSearchStringEscape() throws SQLException {
+ return metaData.getSearchStringEscape();
+ }
+
+ @Override
+ public String getExtraNameCharacters() throws SQLException {
+ return metaData.getExtraNameCharacters();
+ }
+
+ @Override
+ public boolean supportsAlterTableWithAddColumn() throws SQLException {
+ return metaData.supportsAlterTableWithAddColumn();
+ }
+
+ @Override
+ public boolean supportsAlterTableWithDropColumn() throws SQLException {
+ return metaData.supportsAlterTableWithDropColumn();
+ }
+
+ @Override
+ public boolean supportsColumnAliasing() throws SQLException {
+ return metaData.supportsColumnAliasing();
+ }
+
+ @Override
+ public boolean nullPlusNonNullIsNull() throws SQLException {
+ return metaData.nullPlusNonNullIsNull();
+ }
+
+ @Override
+ public boolean supportsConvert() throws SQLException {
+ return metaData.supportsConvert();
+ }
+
+ @Override
+ public boolean supportsConvert(int fromType, int toType) throws SQLException {
+ return metaData.supportsConvert();
+ }
+
+ @Override
+ public boolean supportsTableCorrelationNames() throws SQLException {
+ return metaData.supportsTableCorrelationNames();
+ }
+
+ @Override
+ public boolean supportsDifferentTableCorrelationNames() throws SQLException {
+ return metaData.supportsDifferentTableCorrelationNames();
+ }
+
+ @Override
+ public boolean supportsExpressionsInOrderBy() throws SQLException {
+ return metaData.supportsExpressionsInOrderBy();
+ }
+
+ @Override
+ public boolean supportsOrderByUnrelated() throws SQLException {
+ return metaData.supportsOrderByUnrelated();
+ }
+
+ @Override
+ public boolean supportsGroupBy() throws SQLException {
+ return metaData.supportsGroupBy();
+ }
+
+ @Override
+ public boolean supportsGroupByUnrelated() throws SQLException {
+ return metaData.supportsGroupByUnrelated();
+ }
+
+ @Override
+ public boolean supportsGroupByBeyondSelect() throws SQLException {
+ return metaData.supportsGroupByBeyondSelect();
+ }
+
+ @Override
+ public boolean supportsLikeEscapeClause() throws SQLException {
+ return metaData.supportsLikeEscapeClause();
+ }
+
+ @Override
+ public boolean supportsMultipleResultSets() throws SQLException {
+ return metaData.supportsMultipleResultSets();
+ }
+
+ @Override
+ public boolean supportsMultipleTransactions() throws SQLException {
+ return metaData.supportsMultipleTransactions();
+ }
+
+ @Override
+ public boolean supportsNonNullableColumns() throws SQLException {
+ return metaData.supportsNonNullableColumns();
+ }
+
+ @Override
+ public boolean supportsMinimumSQLGrammar() throws SQLException {
+ return metaData.supportsMinimumSQLGrammar();
+ }
+
+ @Override
+ public boolean supportsCoreSQLGrammar() throws SQLException {
+ return metaData.supportsCoreSQLGrammar();
+ }
+
+ @Override
+ public boolean supportsExtendedSQLGrammar() throws SQLException {
+ return metaData.supportsExtendedSQLGrammar();
+ }
+
+ @Override
+ public boolean supportsANSI92EntryLevelSQL() throws SQLException {
+ return metaData.supportsANSI92EntryLevelSQL();
+ }
+
+ @Override
+ public boolean supportsANSI92IntermediateSQL() throws SQLException {
+ return metaData.supportsANSI92IntermediateSQL();
+ }
+
+ @Override
+ public boolean supportsANSI92FullSQL() throws SQLException {
+ return metaData.supportsANSI92FullSQL();
+ }
+
+ @Override
+ public boolean supportsIntegrityEnhancementFacility() throws SQLException {
+ return metaData.supportsIntegrityEnhancementFacility();
+ }
+
+ @Override
+ public boolean supportsOuterJoins() throws SQLException {
+ return metaData.supportsOuterJoins();
+ }
+
+ @Override
+ public boolean supportsFullOuterJoins() throws SQLException {
+ return metaData.supportsFullOuterJoins();
+ }
+
+ @Override
+ public boolean supportsLimitedOuterJoins() throws SQLException {
+ return metaData.supportsLimitedOuterJoins();
+ }
+
+ @Override
+ public String getSchemaTerm() throws SQLException {
+ return metaData.getSchemaTerm();
+ }
+
+ @Override
+ public String getProcedureTerm() throws SQLException {
+ return metaData.getProcedureTerm();
+ }
+
+ @Override
+ public String getCatalogTerm() throws SQLException {
+ return metaData.getCatalogTerm();
+ }
+
+ @Override
+ public boolean isCatalogAtStart() throws SQLException {
+ return metaData.isCatalogAtStart();
+ }
+
+ @Override
+ public String getCatalogSeparator() throws SQLException {
+ return metaData.getCatalogSeparator();
+ }
+
+ @Override
+ public boolean supportsSchemasInDataManipulation() throws SQLException {
+ return metaData.supportsSchemasInDataManipulation();
+ }
+
+ @Override
+ public boolean supportsSchemasInProcedureCalls() throws SQLException {
+ return metaData.supportsSchemasInProcedureCalls();
+ }
+
+ @Override
+ public boolean supportsSchemasInTableDefinitions() throws SQLException {
+ return metaData.supportsSchemasInTableDefinitions();
+ }
+
+ @Override
+ public boolean supportsSchemasInIndexDefinitions() throws SQLException {
+ return metaData.supportsSchemasInIndexDefinitions();
+ }
+
+ @Override
+ public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
+ return metaData.supportsSchemasInPrivilegeDefinitions();
+ }
+
+ @Override
+ public boolean supportsCatalogsInDataManipulation() throws SQLException {
+ return metaData.supportsCatalogsInDataManipulation();
+ }
+
+ @Override
+ public boolean supportsCatalogsInProcedureCalls() throws SQLException {
+ return metaData.supportsCatalogsInProcedureCalls();
+ }
+
+ @Override
+ public boolean supportsCatalogsInTableDefinitions() throws SQLException {
+ return metaData.supportsCatalogsInTableDefinitions();
+ }
+
+ @Override
+ public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
+ return metaData.supportsCatalogsInIndexDefinitions();
+ }
+
+ @Override
+ public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
+ return metaData.supportsCatalogsInPrivilegeDefinitions();
+ }
+
+ @Override
+ public boolean supportsPositionedDelete() throws SQLException {
+ return metaData.supportsPositionedDelete();
+ }
+
+ @Override
+ public boolean supportsPositionedUpdate() throws SQLException {
+ return metaData.supportsPositionedUpdate();
+ }
+
+ @Override
+ public boolean supportsSelectForUpdate() throws SQLException {
+ return metaData.supportsSelectForUpdate();
+ }
+
+ @Override
+ public boolean supportsStoredProcedures() throws SQLException {
+ return metaData.supportsStoredProcedures();
+ }
+
+ @Override
+ public boolean supportsSubqueriesInComparisons() throws SQLException {
+ return metaData.supportsSubqueriesInComparisons();
+ }
+
+ @Override
+ public boolean supportsSubqueriesInExists() throws SQLException {
+ return metaData.supportsSubqueriesInExists();
+ }
+
+ @Override
+ public boolean supportsSubqueriesInIns() throws SQLException {
+ return metaData.supportsSubqueriesInIns();
+ }
+
+ @Override
+ public boolean supportsSubqueriesInQuantifieds() throws SQLException {
+ return metaData.supportsSubqueriesInQuantifieds();
+ }
+
+ @Override
+ public boolean supportsCorrelatedSubqueries() throws SQLException {
+ return metaData.supportsCorrelatedSubqueries();
+ }
+
+ @Override
+ public boolean supportsUnion() throws SQLException {
+ return metaData.supportsUnion();
+ }
+
+ @Override
+ public boolean supportsUnionAll() throws SQLException {
+ return metaData.supportsUnionAll();
+ }
+
+ @Override
+ public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
+ return metaData.supportsOpenCursorsAcrossCommit();
+ }
+
+ @Override
+ public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
+ return metaData.supportsOpenCursorsAcrossRollback();
+ }
+
+ @Override
+ public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
+ return metaData.supportsOpenStatementsAcrossCommit();
+ }
+
+ @Override
+ public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
+ return metaData.supportsOpenStatementsAcrossRollback();
+ }
+
+ @Override
+ public int getMaxBinaryLiteralLength() throws SQLException {
+ return metaData.getMaxBinaryLiteralLength();
+ }
+
+ @Override
+ public int getMaxCharLiteralLength() throws SQLException {
+ return metaData.getMaxCharLiteralLength();
+ }
+
+ @Override
+ public int getMaxColumnNameLength() throws SQLException {
+ return metaData.getMaxColumnNameLength();
+ }
+
+ @Override
+ public int getMaxColumnsInGroupBy() throws SQLException {
+ return metaData.getMaxColumnsInGroupBy();
+ }
+
+ @Override
+ public int getMaxColumnsInIndex() throws SQLException {
+ return metaData.getMaxColumnsInIndex();
+ }
+
+ @Override
+ public int getMaxColumnsInOrderBy() throws SQLException {
+ return metaData.getMaxColumnsInOrderBy();
+ }
+
+ @Override
+ public int getMaxColumnsInSelect() throws SQLException {
+ return metaData.getMaxColumnsInSelect();
+ }
+
+ @Override
+ public int getMaxColumnsInTable() throws SQLException {
+ return metaData.getMaxColumnsInTable();
+ }
+
+ @Override
+ public int getMaxConnections() throws SQLException {
+ return metaData.getMaxConnections();
+ }
+
+ @Override
+ public int getMaxCursorNameLength() throws SQLException {
+ return metaData.getMaxCursorNameLength();
+ }
+
+ @Override
+ public int getMaxIndexLength() throws SQLException {
+ return metaData.getMaxIndexLength();
+ }
+
+ @Override
+ public int getMaxSchemaNameLength() throws SQLException {
+ return metaData.getMaxSchemaNameLength();
+ }
+
+ @Override
+ public int getMaxProcedureNameLength() throws SQLException {
+ return metaData.getMaxProcedureNameLength();
+ }
+
+ @Override
+ public int getMaxCatalogNameLength() throws SQLException {
+ return metaData.getMaxCatalogNameLength();
+ }
+
+ @Override
+ public int getMaxRowSize() throws SQLException {
+ return metaData.getMaxRowSize();
+ }
+
+ @Override
+ public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
+ return metaData.doesMaxRowSizeIncludeBlobs();
+ }
+
+ @Override
+ public int getMaxStatementLength() throws SQLException {
+ return metaData.getMaxStatementLength();
+ }
+
+ @Override
+ public int getMaxStatements() throws SQLException {
+ return metaData.getMaxStatements();
+ }
+
+ @Override
+ public int getMaxTableNameLength() throws SQLException {
+ return metaData.getMaxTableNameLength();
+ }
+
+ @Override
+ public int getMaxTablesInSelect() throws SQLException {
+ return metaData.getMaxTablesInSelect();
+ }
+
+ @Override
+ public int getMaxUserNameLength() throws SQLException {
+ return metaData.getMaxUserNameLength();
+ }
+
+ @Override
+ public int getDefaultTransactionIsolation() throws SQLException {
+ return metaData.getDefaultTransactionIsolation();
+ }
+
+ @Override
+ public boolean supportsTransactions() throws SQLException {
+ return metaData.supportsTransactions();
+ }
+
+ @Override
+ public boolean supportsTransactionIsolationLevel(int level) throws SQLException {
+ return metaData.supportsTransactionIsolationLevel(level);
+ }
+
+ @Override
+ public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
+ return metaData.supportsDataDefinitionAndDataManipulationTransactions();
+ }
+
+ @Override
+ public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
+ return metaData.supportsDataManipulationTransactionsOnly();
+ }
+
+ @Override
+ public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
+ return metaData.dataDefinitionCausesTransactionCommit();
+ }
+
+ @Override
+ public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
+ return metaData.dataDefinitionIgnoredInTransactions();
+ }
+
+ @Override
+ public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException {
+ return metaData.getProcedures(catalog, schemaPattern, procedureNamePattern);
+ }
+
+ @Override
+ public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException {
+ return metaData.getProcedureColumns(catalog, schemaPattern, procedureNamePattern, columnNamePattern);
+ }
+
+ @Override
+ public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException {
+ return metaData.getTables(catalog, schemaPattern, tableNamePattern, types);
+ }
+
+ @Override
+ public ResultSet getSchemas() throws SQLException {
+ return metaData.getSchemas();
+ }
+
+ @Override
+ public ResultSet getCatalogs() throws SQLException {
+ return metaData.getCatalogs();
+ }
+
+ @Override
+ public ResultSet getTableTypes() throws SQLException {
+ return metaData.getTableTypes();
+ }
+
+ @Override
+ public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException {
+ return metaData.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern);
+ }
+
+ @Override
+ public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException {
+ return metaData.getColumnPrivileges(catalog, schema, table, columnNamePattern);
+ }
+
+ @Override
+ public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
+ return metaData.getTablePrivileges(catalog, schemaPattern, tableNamePattern);
+ }
+
+ @Override
+ public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException {
+ return metaData.getBestRowIdentifier(catalog, schema, table, scope, nullable);
+ }
+
+ @Override
+ public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException {
+ return metaData.getVersionColumns(catalog, schema, table);
+ }
+
+ @Override
+ public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
+ return metaData.getPrimaryKeys(catalog, schema, table);
+ }
+
+ @Override
+ public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException {
+ return metaData.getImportedKeys(catalog, schema, table);
+ }
+
+ @Override
+ public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException {
+ return metaData.getExportedKeys(catalog, schema, table);
+ }
+
+ @Override
+ public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException {
+ return metaData.getCrossReference(parentCatalog, parentSchema, parentTable, foreignCatalog, foreignSchema, foreignTable);
+ }
+
+ @Override
+ public ResultSet getTypeInfo() throws SQLException {
+ return metaData.getTypeInfo();
+ }
+
+ @Override
+ public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException {
+ return metaData.getIndexInfo(catalog, schema, table, unique, approximate);
+ }
+
+ @Override
+ public boolean supportsResultSetType(int type) throws SQLException {
+ return metaData.supportsResultSetType(type);
+ }
+
+ @Override
+ public boolean supportsResultSetConcurrency(int type, int concurrency) throws SQLException {
+ return metaData.supportsResultSetConcurrency(type, concurrency);
+ }
+
+ @Override
+ public boolean ownUpdatesAreVisible(int type) throws SQLException {
+ return metaData.ownUpdatesAreVisible(type);
+ }
+
+ @Override
+ public boolean ownDeletesAreVisible(int type) throws SQLException {
+ return metaData.ownDeletesAreVisible(type);
+ }
+
+ @Override
+ public boolean ownInsertsAreVisible(int type) throws SQLException {
+ return metaData.ownInsertsAreVisible(type);
+ }
+
+ @Override
+ public boolean othersUpdatesAreVisible(int type) throws SQLException {
+ return metaData.othersUpdatesAreVisible(type);
+ }
+
+ @Override
+ public boolean othersDeletesAreVisible(int type) throws SQLException {
+ return metaData.othersDeletesAreVisible(type);
+ }
+
+ @Override
+ public boolean othersInsertsAreVisible(int type) throws SQLException {
+ return metaData.othersInsertsAreVisible(type);
+ }
+
+ @Override
+ public boolean updatesAreDetected(int type) throws SQLException {
+ return metaData.updatesAreDetected(type);
+ }
+
+ @Override
+ public boolean deletesAreDetected(int type) throws SQLException {
+ return metaData.deletesAreDetected(type);
+ }
+
+ @Override
+ public boolean insertsAreDetected(int type) throws SQLException {
+ return metaData.insertsAreDetected(type);
+ }
+
+ @Override
+ public boolean supportsBatchUpdates() throws SQLException {
+ return metaData.supportsBatchUpdates();
+ }
+
+ @Override
+ public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException {
+ return metaData.getUDTs(catalog, schemaPattern, typeNamePattern, types);
+ }
+
+ @Override
+ public Connection getConnection() throws SQLException {
+ return metaData.getConnection();
+ }
+
+ @Override
+ public boolean supportsSavepoints() throws SQLException {
+ return metaData.supportsSavepoints();
+ }
+
+ @Override
+ public boolean supportsNamedParameters() throws SQLException {
+ return metaData.supportsNamedParameters();
+ }
+
+ @Override
+ public boolean supportsMultipleOpenResults() throws SQLException {
+ return metaData.supportsMultipleOpenResults();
+ }
+
+ @Override
+ public boolean supportsGetGeneratedKeys() throws SQLException {
+ return metaData.supportsGetGeneratedKeys();
+ }
+
+ @Override
+ public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) throws SQLException {
+ return metaData.getSuperTypes(catalog, schemaPattern, typeNamePattern);
+ }
+
+ @Override
+ public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
+ return metaData.getSuperTypes(catalog, schemaPattern, tableNamePattern);
+ }
+
+ @Override
+ public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern) throws SQLException {
+ return metaData.getAttributes(catalog, schemaPattern, typeNamePattern, attributeNamePattern);
+ }
+
+ @Override
+ public boolean supportsResultSetHoldability(int holdability) throws SQLException {
+ return metaData.supportsResultSetHoldability(holdability);
+ }
+
+ @Override
+ public int getResultSetHoldability() throws SQLException {
+ return metaData.getResultSetHoldability();
+ }
+
+ @Override
+ public int getDatabaseMajorVersion() throws SQLException {
+ return metaData.getDatabaseMajorVersion();
+ }
+
+ @Override
+ public int getDatabaseMinorVersion() throws SQLException {
+ return metaData.getDatabaseMinorVersion();
+ }
+
+ @Override
+ public int getJDBCMajorVersion() throws SQLException {
+ return metaData.getJDBCMajorVersion();
+ }
+
+ @Override
+ public int getJDBCMinorVersion() throws SQLException {
+ return metaData.getJDBCMinorVersion();
+ }
+
+ @Override
+ public int getSQLStateType() throws SQLException {
+ return metaData.getSQLStateType();
+ }
+
+ @Override
+ public boolean locatorsUpdateCopy() throws SQLException {
+ return metaData.locatorsUpdateCopy();
+ }
+
+ @Override
+ public boolean supportsStatementPooling() throws SQLException {
+ return metaData.supportsStatementPooling();
+ }
+
+ @Override
+ public RowIdLifetime getRowIdLifetime() throws SQLException {
+ return metaData.getRowIdLifetime();
+ }
+
+ @Override
+ public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException {
+ return metaData.getSchemas(catalog, schemaPattern);
+ }
+
+ @Override
+ public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
+ return metaData.supportsStoredFunctionsUsingCallSyntax();
+ }
+
+ @Override
+ public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
+ return metaData.autoCommitFailureClosesAllResultSets();
+ }
+
+ @Override
+ public ResultSet getClientInfoProperties() throws SQLException {
+ return metaData.getClientInfoProperties();
+ }
+
+ @Override
+ public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) throws SQLException {
+ return metaData.getFunctions(catalog, schemaPattern, functionNamePattern);
+ }
+
+ @Override
+ public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern) throws SQLException {
+ return metaData.getFunctionColumns(catalog, schemaPattern, functionNamePattern, columnNamePattern);
+ }
+
+ @Override
+ public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException {
+ return metaData.getPseudoColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern);
+ }
+
+ @Override
+ public boolean generatedKeyAlwaysReturned() throws SQLException {
+ return metaData.generatedKeyAlwaysReturned();
+ }
+
+ @Override
+ public T unwrap(Class iface) throws SQLException {
+ return metaData.unwrap(iface);
+ }
+
+ @Override
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return metaData.isWrapperFor(iface);
+ }
+}
diff --git a/agent/src/main/java/com/fanruan/agent/jdbc/AgentParameterMetaData.java b/agent/src/main/java/com/fanruan/agent/jdbc/AgentParameterMetaData.java
new file mode 100644
index 0000000..9f32467
--- /dev/null
+++ b/agent/src/main/java/com/fanruan/agent/jdbc/AgentParameterMetaData.java
@@ -0,0 +1,73 @@
+package com.fanruan.agent.jdbc;
+
+import java.sql.ParameterMetaData;
+import java.sql.SQLException;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/25 16:41
+ */
+
+
+public class AgentParameterMetaData implements ParameterMetaData {
+ private ParameterMetaData metaData;
+
+ public AgentParameterMetaData(ParameterMetaData metaData){
+ this.metaData = metaData;
+ }
+
+ @Override
+ public int getParameterCount() throws SQLException {
+ return metaData.getParameterCount();
+ }
+
+ @Override
+ public int isNullable(int param) throws SQLException {
+ return metaData.isNullable(param);
+ }
+
+ @Override
+ public boolean isSigned(int param) throws SQLException {
+ return metaData.isSigned(param);
+ }
+
+ @Override
+ public int getPrecision(int param) throws SQLException {
+ return metaData.getPrecision(param);
+ }
+
+ @Override
+ public int getScale(int param) throws SQLException {
+ return metaData.getScale(param);
+ }
+
+ @Override
+ public int getParameterType(int param) throws SQLException {
+ return metaData.getParameterType(param);
+ }
+
+ @Override
+ public String getParameterTypeName(int param) throws SQLException {
+ return metaData.getParameterTypeName(param);
+ }
+
+ @Override
+ public String getParameterClassName(int param) throws SQLException {
+ return metaData.getParameterClassName(param);
+ }
+
+ @Override
+ public int getParameterMode(int param) throws SQLException {
+ return metaData.getParameterMode(param);
+ }
+
+ @Override
+ public T unwrap(Class iface) throws SQLException {
+ return metaData.unwrap(iface);
+ }
+
+ @Override
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return metaData.isWrapperFor(iface);
+ }
+}
diff --git a/agent/src/main/java/com/fanruan/agent/jdbc/AgentStruct.java b/agent/src/main/java/com/fanruan/agent/jdbc/AgentStruct.java
new file mode 100644
index 0000000..0fd76fb
--- /dev/null
+++ b/agent/src/main/java/com/fanruan/agent/jdbc/AgentStruct.java
@@ -0,0 +1,32 @@
+package com.fanruan.agent.jdbc;
+
+import java.sql.SQLException;
+import java.sql.Struct;
+import java.util.Map;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/31 17:04
+ */
+public class AgentStruct implements Struct {
+ Struct struct;
+
+ AgentStruct(Struct struct){
+ this.struct = struct;
+ }
+
+ @Override
+ public String getSQLTypeName() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public Object[] getAttributes() throws SQLException {
+ return new Object[0];
+ }
+
+ @Override
+ public Object[] getAttributes(Map> map) throws SQLException {
+ return new Object[0];
+ }
+}
diff --git a/agent/src/main/java/com/fanruan/agent/jdbc/connection/AgentConnection.java b/agent/src/main/java/com/fanruan/agent/jdbc/connection/AgentConnection.java
index 2b5516a..def727a 100644
--- a/agent/src/main/java/com/fanruan/agent/jdbc/connection/AgentConnection.java
+++ b/agent/src/main/java/com/fanruan/agent/jdbc/connection/AgentConnection.java
@@ -1,5 +1,7 @@
package com.fanruan.agent.jdbc.connection;
+import com.fanruan.agent.jdbc.AgentDataBaseMetaData;
+import com.fanruan.agent.jdbc.statement.AgentCallableStatement;
import com.fanruan.agent.jdbc.statement.AgentPreparedStatement;
import com.fanruan.agent.jdbc.statement.AgentStatement;
@@ -32,7 +34,8 @@ public class AgentConnection implements Connection {
@Override
public CallableStatement prepareCall(String sql) throws SQLException {
- return conn.prepareCall(sql);
+ CallableStatement cst = this.conn.prepareCall(sql);
+ return new AgentCallableStatement(cst);
}
@Override
@@ -72,7 +75,7 @@ public class AgentConnection implements Connection {
@Override
public DatabaseMetaData getMetaData() throws SQLException {
- return conn.getMetaData();
+ return new AgentDataBaseMetaData(conn.getMetaData());
}
@Override
@@ -117,17 +120,17 @@ public class AgentConnection implements Connection {
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
- return conn.createStatement(resultSetType, resultSetConcurrency);
+ return new AgentStatement(conn.createStatement(resultSetType, resultSetConcurrency));
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
- return conn.prepareStatement(sql, resultSetType, resultSetConcurrency);
+ return new AgentPreparedStatement(conn.prepareStatement(sql, resultSetType, resultSetConcurrency));
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
- return conn.prepareCall(sql, resultSetType, resultSetConcurrency);
+ return new AgentCallableStatement(conn.prepareCall(sql, resultSetType, resultSetConcurrency));
}
@Override
@@ -172,32 +175,32 @@ public class AgentConnection implements Connection {
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
- return conn.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
+ return new AgentStatement(conn.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability));
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
- return conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ return new AgentPreparedStatement(conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
- return conn.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ return new AgentCallableStatement(conn.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
}
@Override
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
- return conn.prepareStatement(sql, autoGeneratedKeys);
+ return new AgentPreparedStatement(conn.prepareStatement(sql, autoGeneratedKeys));
}
@Override
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
- return conn.prepareStatement(sql, columnIndexes);
+ return new AgentPreparedStatement(conn.prepareStatement(sql, columnIndexes));
}
@Override
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
- return conn.prepareStatement(sql, columnNames);
+ return new AgentPreparedStatement(conn.prepareStatement(sql, columnNames));
}
@Override
diff --git a/agent/src/main/java/com/fanruan/agent/jdbc/statement/AgentCallableStatement.java b/agent/src/main/java/com/fanruan/agent/jdbc/statement/AgentCallableStatement.java
new file mode 100644
index 0000000..1dd66e9
--- /dev/null
+++ b/agent/src/main/java/com/fanruan/agent/jdbc/statement/AgentCallableStatement.java
@@ -0,0 +1,1084 @@
+package com.fanruan.agent.jdbc.statement;
+
+import com.fanruan.agent.jdbc.AgentParameterMetaData;
+
+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.Map;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/24 16:18
+ */
+public class AgentCallableStatement implements java.sql.CallableStatement {
+
+ final private CallableStatement cst;
+
+ public AgentCallableStatement(CallableStatement callablestatement) {
+ this.cst = callablestatement;
+ }
+
+ @Override
+ public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException {
+ cst.registerOutParameter(parameterIndex, sqlType);
+ }
+
+ @Override
+ public void registerOutParameter(int parameterIndex, int sqlType, int scale) throws SQLException {
+ cst.registerOutParameter(parameterIndex, sqlType, scale);
+ }
+
+ @Override
+ public boolean wasNull() throws SQLException {
+ return cst.wasNull();
+ }
+
+ @Override
+ public String getString(int parameterIndex) throws SQLException {
+ return cst.getString(parameterIndex);
+ }
+
+ @Override
+ public boolean getBoolean(int parameterIndex) throws SQLException {
+ return cst.getBoolean(parameterIndex);
+ }
+
+ @Override
+ public byte getByte(int parameterIndex) throws SQLException {
+ return cst.getByte(parameterIndex);
+ }
+
+ @Override
+ public short getShort(int parameterIndex) throws SQLException {
+ return cst.getShort(parameterIndex);
+ }
+
+ @Override
+ public int getInt(int parameterIndex) throws SQLException {
+ return cst.getInt(parameterIndex);
+ }
+
+ @Override
+ public long getLong(int parameterIndex) throws SQLException {
+ return cst.getLong(parameterIndex);
+ }
+
+ @Override
+ public float getFloat(int parameterIndex) throws SQLException {
+ return cst.getFloat(parameterIndex);
+ }
+
+ @Override
+ public double getDouble(int parameterIndex) throws SQLException {
+ return cst.getDouble(parameterIndex);
+ }
+
+ @Override
+ public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException {
+ return cst.getBigDecimal(parameterIndex, scale);
+ }
+
+ @Override
+ public byte[] getBytes(int parameterIndex) throws SQLException {
+ return cst.getBytes(parameterIndex);
+ }
+
+ @Override
+ public Date getDate(int parameterIndex) throws SQLException {
+ return cst.getDate(parameterIndex);
+ }
+
+ @Override
+ public Time getTime(int parameterIndex) throws SQLException {
+ return cst.getTime(parameterIndex);
+ }
+
+ @Override
+ public Timestamp getTimestamp(int parameterIndex) throws SQLException {
+ return cst.getTimestamp(parameterIndex);
+ }
+
+ @Override
+ public Object getObject(int parameterIndex) throws SQLException {
+ return cst.getObject(parameterIndex);
+ }
+
+ @Override
+ public BigDecimal getBigDecimal(int parameterIndex) throws SQLException {
+ return cst.getBigDecimal(parameterIndex);
+ }
+
+ @Override
+ public Object getObject(int parameterIndex, Map> map) throws SQLException {
+ return cst.getObject(parameterIndex, map);
+ }
+
+ @Override
+ public Ref getRef(int parameterIndex) throws SQLException {
+ return cst.getRef(parameterIndex);
+ }
+
+ @Override
+ public Blob getBlob(int parameterIndex) throws SQLException {
+ return cst.getBlob(parameterIndex);
+ }
+
+ @Override
+ public Clob getClob(int parameterIndex) throws SQLException {
+ return cst.getClob(parameterIndex);
+ }
+
+ @Override
+ public Array getArray(int parameterIndex) throws SQLException {
+ return cst.getArray(parameterIndex);
+ }
+
+ @Override
+ public Date getDate(int parameterIndex, Calendar cal) throws SQLException {
+ return cst.getDate(parameterIndex, cal);
+ }
+
+ @Override
+ public Time getTime(int parameterIndex, Calendar cal) throws SQLException {
+ return cst.getTime(parameterIndex, cal);
+ }
+
+ @Override
+ public Timestamp getTimestamp(int parameterIndex, Calendar cal) throws SQLException {
+ return cst.getTimestamp(parameterIndex, cal);
+ }
+
+ @Override
+ public void registerOutParameter(int parameterIndex, int sqlType, String typeName) throws SQLException {
+ cst.registerOutParameter(parameterIndex, sqlType, typeName);
+ }
+
+ @Override
+ public void registerOutParameter(String parameterName, int sqlType) throws SQLException {
+ cst.registerOutParameter(parameterName, sqlType);
+ }
+
+ @Override
+ public void registerOutParameter(String parameterName, int sqlType, int scale) throws SQLException {
+ cst.registerOutParameter(parameterName, sqlType, scale);
+ }
+
+ @Override
+ public void registerOutParameter(String parameterName, int sqlType, String typeName) throws SQLException {
+ cst.registerOutParameter(parameterName, sqlType, typeName);
+ }
+
+ @Override
+ public URL getURL(int parameterIndex) throws SQLException {
+ return cst.getURL(parameterIndex);
+ }
+
+ @Override
+ public void setURL(String parameterName, URL val) throws SQLException {
+ cst.setURL(parameterName, val);
+ }
+
+ @Override
+ public void setNull(String parameterName, int sqlType) throws SQLException {
+ cst.setNull(parameterName, sqlType);
+ }
+
+ @Override
+ public void setBoolean(String parameterName, boolean x) throws SQLException {
+ cst.setBoolean(parameterName, x);
+ }
+
+ @Override
+ public void setByte(String parameterName, byte x) throws SQLException {
+ cst.setByte(parameterName, x);
+ }
+
+ @Override
+ public void setShort(String parameterName, short x) throws SQLException {
+ cst.setShort(parameterName, x);
+ }
+
+ @Override
+ public void setInt(String parameterName, int x) throws SQLException {
+ cst.setInt(parameterName, x);
+ }
+
+ @Override
+ public void setLong(String parameterName, long x) throws SQLException {
+ cst.setLong(parameterName, x);
+ }
+
+ @Override
+ public void setFloat(String parameterName, float x) throws SQLException {
+ cst.setFloat(parameterName, x);
+ }
+
+ @Override
+ public void setDouble(String parameterName, double x) throws SQLException {
+ cst.setDouble(parameterName, x);
+ }
+
+ @Override
+ public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException {
+ cst.setBigDecimal(parameterName, x);
+ }
+
+ @Override
+ public void setString(String parameterName, String x) throws SQLException {
+ cst.setString(parameterName, x);
+ }
+
+ @Override
+ public void setBytes(String parameterName, byte[] x) throws SQLException {
+ cst.setBytes(parameterName, x);
+ }
+
+ @Override
+ public void setDate(String parameterName, Date x) throws SQLException {
+ cst.setDate(parameterName, x);
+ }
+
+ @Override
+ public void setTime(String parameterName, Time x) throws SQLException {
+ cst.setTime(parameterName, x);
+ }
+
+ @Override
+ public void setTimestamp(String parameterName, Timestamp x) throws SQLException {
+ cst.setTimestamp(parameterName, x);
+ }
+
+ @Override
+ public void setAsciiStream(String parameterName, InputStream x, int length) throws SQLException {
+ cst.setAsciiStream(parameterName, x, length);
+ }
+
+ @Override
+ public void setBinaryStream(String parameterName, InputStream x, int length) throws SQLException {
+ cst.setBinaryStream(parameterName, x, length);
+ }
+
+ @Override
+ public void setObject(String parameterName, Object x, int targetSqlType, int scale) throws SQLException {
+ cst.setObject(parameterName, x, targetSqlType, scale);
+ }
+
+ @Override
+ public void setObject(String parameterName, Object x, int targetSqlType) throws SQLException {
+ cst.setObject(parameterName, x, targetSqlType);
+ }
+
+ @Override
+ public void setObject(String parameterName, Object x) throws SQLException {
+ cst.setObject(parameterName, x);
+ }
+
+ @Override
+ public void setCharacterStream(String parameterName, Reader reader, int length) throws SQLException {
+ cst.setCharacterStream(parameterName, reader, length);
+ }
+
+ @Override
+ public void setDate(String parameterName, Date x, Calendar cal) throws SQLException {
+ cst.setDate(parameterName, x, cal);
+ }
+
+ @Override
+ public void setTime(String parameterName, Time x, Calendar cal) throws SQLException {
+ cst.setTime(parameterName, x, cal);
+ }
+
+ @Override
+ public void setTimestamp(String parameterName, Timestamp x, Calendar cal) throws SQLException {
+ cst.setTimestamp(parameterName, x, cal);
+ }
+
+ @Override
+ public void setNull(String parameterName, int sqlType, String typeName) throws SQLException {
+ cst.setNull(parameterName, sqlType, typeName);
+ }
+
+ @Override
+ public String getString(String parameterName) throws SQLException {
+ return cst.getString(parameterName);
+ }
+
+ @Override
+ public boolean getBoolean(String parameterName) throws SQLException {
+ return cst.getBoolean(parameterName);
+ }
+
+ @Override
+ public byte getByte(String parameterName) throws SQLException {
+ return cst.getByte(parameterName);
+ }
+
+ @Override
+ public short getShort(String parameterName) throws SQLException {
+ return cst.getShort(parameterName);
+ }
+
+ @Override
+ public int getInt(String parameterName) throws SQLException {
+ return cst.getInt(parameterName);
+ }
+
+ @Override
+ public long getLong(String parameterName) throws SQLException {
+ return cst.getLong(parameterName);
+ }
+
+ @Override
+ public float getFloat(String parameterName) throws SQLException {
+ return cst.getFloat(parameterName);
+ }
+
+ @Override
+ public double getDouble(String parameterName) throws SQLException {
+ return cst.getDouble(parameterName);
+ }
+
+ @Override
+ public byte[] getBytes(String parameterName) throws SQLException {
+ return cst.getBytes(parameterName);
+ }
+
+ @Override
+ public Date getDate(String parameterName) throws SQLException {
+ return cst.getDate(parameterName);
+ }
+
+ @Override
+ public Time getTime(String parameterName) throws SQLException {
+ return cst.getTime(parameterName);
+ }
+
+ @Override
+ public Timestamp getTimestamp(String parameterName) throws SQLException {
+ return cst.getTimestamp(parameterName);
+ }
+
+ @Override
+ public Object getObject(String parameterName) throws SQLException {
+ return cst.getObject(parameterName);
+ }
+
+ @Override
+ public BigDecimal getBigDecimal(String parameterName) throws SQLException {
+ return cst.getBigDecimal(parameterName);
+ }
+
+ @Override
+ public Object getObject(String parameterName, Map> map) throws SQLException {
+ return cst.getObject(parameterName, map);
+ }
+
+ @Override
+ public Ref getRef(String parameterName) throws SQLException {
+ return cst.getRef(parameterName);
+ }
+
+ @Override
+ public Blob getBlob(String parameterName) throws SQLException {
+ return cst.getBlob(parameterName);
+ }
+
+ @Override
+ public Clob getClob(String parameterName) throws SQLException {
+ return cst.getClob(parameterName);
+ }
+
+ @Override
+ public Array getArray(String parameterName) throws SQLException {
+ return cst.getArray(parameterName);
+ }
+
+ @Override
+ public Date getDate(String parameterName, Calendar cal) throws SQLException {
+ return cst.getDate(parameterName, cal);
+ }
+
+ @Override
+ public Time getTime(String parameterName, Calendar cal) throws SQLException {
+ return cst.getTime(parameterName, cal);
+ }
+
+ @Override
+ public Timestamp getTimestamp(String parameterName, Calendar cal) throws SQLException {
+ return cst.getTimestamp(parameterName, cal);
+ }
+
+ @Override
+ public URL getURL(String parameterName) throws SQLException {
+ return cst.getURL(parameterName);
+ }
+
+ @Override
+ public RowId getRowId(int parameterIndex) throws SQLException {
+ return cst.getRowId(parameterIndex);
+ }
+
+ @Override
+ public RowId getRowId(String parameterName) throws SQLException {
+ return cst.getRowId(parameterName);
+ }
+
+ @Override
+ public void setRowId(String parameterName, RowId x) throws SQLException {
+ cst.setRowId(parameterName, x);
+ }
+
+ @Override
+ public void setNString(String parameterName, String value) throws SQLException {
+ cst.setNString(parameterName, value);
+ }
+
+ @Override
+ public void setNCharacterStream(String parameterName, Reader value, long length) throws SQLException {
+ cst.setNCharacterStream(parameterName, value, length);
+ }
+
+ @Override
+ public void setNClob(String parameterName, NClob value) throws SQLException {
+ cst.setNClob(parameterName, value);
+ }
+
+ @Override
+ public void setClob(String parameterName, Reader reader, long length) throws SQLException {
+ cst.setClob(parameterName, reader, length);
+ }
+
+ @Override
+ public void setBlob(String parameterName, InputStream inputStream, long length) throws SQLException {
+ cst.setBlob(parameterName, inputStream, length);
+ }
+
+ @Override
+ public void setNClob(String parameterName, Reader reader, long length) throws SQLException {
+ cst.setNClob(parameterName, reader, length);
+ }
+
+ @Override
+ public NClob getNClob(int parameterIndex) throws SQLException {
+ return cst.getNClob(parameterIndex);
+ }
+
+ @Override
+ public NClob getNClob(String parameterName) throws SQLException {
+ return cst.getNClob(parameterName);
+ }
+
+ @Override
+ public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException {
+ cst.setSQLXML(parameterName, xmlObject);
+ }
+
+ @Override
+ public SQLXML getSQLXML(int parameterIndex) throws SQLException {
+ return cst.getSQLXML(parameterIndex);
+ }
+
+ @Override
+ public SQLXML getSQLXML(String parameterName) throws SQLException {
+ return cst.getSQLXML(parameterName);
+ }
+
+ @Override
+ public String getNString(int parameterIndex) throws SQLException {
+ return cst.getNString(parameterIndex);
+ }
+
+ @Override
+ public String getNString(String parameterName) throws SQLException {
+ return cst.getNString(parameterName);
+ }
+
+ @Override
+ public Reader getNCharacterStream(int parameterIndex) throws SQLException {
+ return cst.getNCharacterStream(parameterIndex);
+ }
+
+ @Override
+ public Reader getNCharacterStream(String parameterName) throws SQLException {
+ return cst.getNCharacterStream(parameterName);
+ }
+
+ @Override
+ public Reader getCharacterStream(int parameterIndex) throws SQLException {
+ return cst.getCharacterStream(parameterIndex);
+ }
+
+ @Override
+ public Reader getCharacterStream(String parameterName) throws SQLException {
+ return cst.getCharacterStream(parameterName);
+ }
+
+ @Override
+ public void setBlob(String parameterName, Blob x) throws SQLException {
+ cst.setBlob(parameterName, x);
+ }
+
+ @Override
+ public void setClob(String parameterName, Clob x) throws SQLException {
+ cst.setClob(parameterName, x);
+ }
+
+ @Override
+ public void setAsciiStream(String parameterName, InputStream x, long length) throws SQLException {
+ cst.setAsciiStream(parameterName, x, length);
+ }
+
+ @Override
+ public void setBinaryStream(String parameterName, InputStream x, long length) throws SQLException {
+ cst.setBinaryStream(parameterName, x, length);
+ }
+
+ @Override
+ public void setCharacterStream(String parameterName, Reader reader, long length) throws SQLException {
+ cst.setCharacterStream(parameterName, reader, length);
+ }
+
+ @Override
+ public void setAsciiStream(String parameterName, InputStream x) throws SQLException {
+ cst.setAsciiStream(parameterName, x);
+ }
+
+ @Override
+ public void setBinaryStream(String parameterName, InputStream x) throws SQLException {
+ cst.setBinaryStream(parameterName, x);
+ }
+
+ @Override
+ public void setCharacterStream(String parameterName, Reader reader) throws SQLException {
+ cst.setCharacterStream(parameterName, reader);
+ }
+
+ @Override
+ public void setNCharacterStream(String parameterName, Reader value) throws SQLException {
+ cst.setNCharacterStream(parameterName, value);
+ }
+
+ @Override
+ public void setClob(String parameterName, Reader reader) throws SQLException {
+ cst.setClob(parameterName, reader);
+ }
+
+ @Override
+ public void setBlob(String parameterName, InputStream inputStream) throws SQLException {
+ cst.setBlob(parameterName, inputStream);
+ }
+
+ @Override
+ public void setNClob(String parameterName, Reader reader) throws SQLException {
+ cst.setNClob(parameterName, reader);
+ }
+
+ @Override
+ public T getObject(int parameterIndex, Class type) throws SQLException {
+ return cst.getObject(parameterIndex, type);
+ }
+
+ @Override
+ public T getObject(String parameterName, Class type) throws SQLException {
+ return cst.getObject(parameterName, type);
+ }
+
+ @Override
+ public ResultSet executeQuery() throws SQLException {
+ return cst.executeQuery();
+ }
+
+ @Override
+ public int executeUpdate() throws SQLException {
+ return cst.executeUpdate();
+ }
+
+ @Override
+ public void setNull(int parameterIndex, int sqlType) throws SQLException {
+ cst.setNull(parameterIndex, sqlType);
+ }
+
+ @Override
+ public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+ cst.setBoolean(parameterIndex, x);
+ }
+
+ @Override
+ public void setByte(int parameterIndex, byte x) throws SQLException {
+ cst.setByte(parameterIndex, x);
+ }
+
+ @Override
+ public void setShort(int parameterIndex, short x) throws SQLException {
+ cst.setShort(parameterIndex, x);
+ }
+
+ @Override
+ public void setInt(int parameterIndex, int x) throws SQLException {
+ cst.setInt(parameterIndex, x);
+ }
+
+ @Override
+ public void setLong(int parameterIndex, long x) throws SQLException {
+ cst.setLong(parameterIndex, x);
+ }
+
+ @Override
+ public void setFloat(int parameterIndex, float x) throws SQLException {
+ cst.setFloat(parameterIndex, x);
+ }
+
+ @Override
+ public void setDouble(int parameterIndex, double x) throws SQLException {
+ cst.setDouble(parameterIndex, x);
+ }
+
+ @Override
+ public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
+ cst.setBigDecimal(parameterIndex, x);
+ }
+
+ @Override
+ public void setString(int parameterIndex, String x) throws SQLException {
+ cst.setString(parameterIndex, x);
+ }
+
+ @Override
+ public void setBytes(int parameterIndex, byte[] x) throws SQLException {
+ cst.setBytes(parameterIndex, x);
+ }
+
+ @Override
+ public void setDate(int parameterIndex, Date x) throws SQLException {
+ cst.setDate(parameterIndex, x);
+ }
+
+ @Override
+ public void setTime(int parameterIndex, Time x) throws SQLException {
+ cst.setTime(parameterIndex, x);
+ }
+
+ @Override
+ public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
+ cst.setTimestamp(parameterIndex, x);
+ }
+
+ @Override
+ public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ cst.setAsciiStream(parameterIndex, x, length);
+ }
+
+ @Override
+ public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ cst.setUnicodeStream(parameterIndex, x, length);
+ }
+
+ @Override
+ public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ cst.setBinaryStream(parameterIndex, x, length);
+ }
+
+ @Override
+ public void clearParameters() throws SQLException {
+ cst.clearParameters();
+ }
+
+ @Override
+ public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
+ cst.setObject(parameterIndex, x, targetSqlType);
+ }
+
+ @Override
+ public void setObject(int parameterIndex, Object x) throws SQLException {
+ cst.setObject(parameterIndex, x);
+ }
+
+ @Override
+ public boolean execute() throws SQLException {
+ return cst.execute();
+ }
+
+ @Override
+ public void addBatch() throws SQLException {
+ cst.addBatch();
+ }
+
+ @Override
+ public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
+ cst.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ @Override
+ public void setRef(int parameterIndex, Ref x) throws SQLException {
+ cst.setRef(parameterIndex, x);
+ }
+
+ @Override
+ public void setBlob(int parameterIndex, Blob x) throws SQLException {
+ cst.setBlob(parameterIndex, x);
+ }
+
+ @Override
+ public void setClob(int parameterIndex, Clob x) throws SQLException {
+ cst.setClob(parameterIndex, x);
+ }
+
+ @Override
+ public void setArray(int parameterIndex, Array x) throws SQLException {
+ cst.setArray(parameterIndex, x);
+ }
+
+ @Override
+ public ResultSetMetaData getMetaData() throws SQLException {
+ return cst.getMetaData();
+ }
+
+ @Override
+ public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
+ cst.setDate(parameterIndex, x, cal);
+ }
+
+ @Override
+ public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
+ cst.setTime(parameterIndex, x, cal);
+ }
+
+ @Override
+ public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
+ cst.setTimestamp(parameterIndex, x, cal);
+ }
+
+ @Override
+ public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
+ cst.setNull(parameterIndex, sqlType, typeName);
+ }
+
+ @Override
+ public void setURL(int parameterIndex, URL x) throws SQLException {
+ cst.setURL(parameterIndex, x);
+ }
+
+ @Override
+ public ParameterMetaData getParameterMetaData() throws SQLException {
+ return new AgentParameterMetaData(cst.getParameterMetaData());
+ }
+
+ @Override
+ public void setRowId(int parameterIndex, RowId x) throws SQLException {
+ cst.setRowId(parameterIndex, x);
+ }
+
+ @Override
+ public void setNString(int parameterIndex, String value) throws SQLException {
+ cst.setNString(parameterIndex, value);
+ }
+
+ @Override
+ public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
+ cst.setNCharacterStream(parameterIndex, value, length);
+ }
+
+ @Override
+ public void setNClob(int parameterIndex, NClob value) throws SQLException {
+ cst.setNClob(parameterIndex, value);
+ }
+
+ @Override
+ public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ cst.setClob(parameterIndex, reader, length);
+ }
+
+ @Override
+ public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+ cst.setBlob(parameterIndex, inputStream, length);
+ }
+
+ @Override
+ public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ cst.setNClob(parameterIndex, reader, length);
+ }
+
+ @Override
+ public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+ cst.setSQLXML(parameterIndex, xmlObject);
+ }
+
+ @Override
+ public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
+ cst.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
+ }
+
+ @Override
+ public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ cst.setAsciiStream(parameterIndex, x, length);
+ }
+
+ @Override
+ public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ cst.setBinaryStream(parameterIndex, x, length);
+ }
+
+ @Override
+ public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
+ cst.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ @Override
+ public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
+ cst.setAsciiStream(parameterIndex, x);
+ }
+
+ @Override
+ public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
+ cst.setBinaryStream(parameterIndex, x);
+ }
+
+ @Override
+ public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+ cst.setCharacterStream(parameterIndex, reader);
+ }
+
+ @Override
+ public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
+ cst.setNCharacterStream(parameterIndex, value);
+ }
+
+ @Override
+ public void setClob(int parameterIndex, Reader reader) throws SQLException {
+ cst.setClob(parameterIndex, reader);
+ }
+
+ @Override
+ public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+ cst.setBlob(parameterIndex, inputStream);
+ }
+
+ @Override
+ public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+ cst.setNClob(parameterIndex, reader);
+ }
+
+ @Override
+ public ResultSet executeQuery(String sql) throws SQLException {
+ return cst.executeQuery(sql);
+ }
+
+ @Override
+ public int executeUpdate(String sql) throws SQLException {
+ return cst.executeUpdate(sql);
+ }
+
+ @Override
+ public void close() throws SQLException {
+ cst.close();
+ }
+
+ @Override
+ public int getMaxFieldSize() throws SQLException {
+ return cst.getMaxFieldSize();
+ }
+
+ @Override
+ public void setMaxFieldSize(int max) throws SQLException {
+ cst.setMaxFieldSize(max);
+ }
+
+ @Override
+ public int getMaxRows() throws SQLException {
+ return cst.getMaxRows();
+ }
+
+ @Override
+ public void setMaxRows(int max) throws SQLException {
+ cst.setMaxRows(max);
+ }
+
+ @Override
+ public void setEscapeProcessing(boolean enable) throws SQLException {
+ cst.setEscapeProcessing(enable);
+ }
+
+ @Override
+ public int getQueryTimeout() throws SQLException {
+ return cst.getQueryTimeout();
+ }
+
+ @Override
+ public void setQueryTimeout(int seconds) throws SQLException {
+ cst.setQueryTimeout(seconds);
+ }
+
+ @Override
+ public void cancel() throws SQLException {
+ cst.cancel();
+ }
+
+ @Override
+ public SQLWarning getWarnings() throws SQLException {
+ return cst.getWarnings();
+ }
+
+ @Override
+ public void clearWarnings() throws SQLException {
+ cst.clearWarnings();
+ }
+
+ @Override
+ public void setCursorName(String name) throws SQLException {
+ cst.setCursorName(name);
+ }
+
+ @Override
+ public boolean execute(String sql) throws SQLException {
+ return cst.execute(sql);
+ }
+
+ @Override
+ public ResultSet getResultSet() throws SQLException {
+ return cst.getResultSet();
+ }
+
+ @Override
+ public int getUpdateCount() throws SQLException {
+ return cst.getUpdateCount();
+ }
+
+ @Override
+ public boolean getMoreResults() throws SQLException {
+ return cst.getMoreResults();
+ }
+
+ @Override
+ public void setFetchDirection(int direction) throws SQLException {
+ cst.setFetchDirection(direction);
+ }
+
+ @Override
+ public int getFetchDirection() throws SQLException {
+ return cst.getFetchDirection();
+ }
+
+ @Override
+ public void setFetchSize(int rows) throws SQLException {
+ cst.setFetchSize(rows);
+ }
+
+ @Override
+ public int getFetchSize() throws SQLException {
+ return cst.getFetchSize();
+ }
+
+ @Override
+ public int getResultSetConcurrency() throws SQLException {
+ return cst.getResultSetConcurrency();
+ }
+
+ @Override
+ public int getResultSetType() throws SQLException {
+ return cst.getResultSetType();
+ }
+
+ @Override
+ public void addBatch(String sql) throws SQLException {
+ cst.addBatch(sql);
+ }
+
+ @Override
+ public void clearBatch() throws SQLException {
+ cst.clearBatch();
+ }
+
+ @Override
+ public int[] executeBatch() throws SQLException {
+ return cst.executeBatch();
+ }
+
+ @Override
+ public Connection getConnection() throws SQLException {
+ return cst.getConnection();
+ }
+
+ @Override
+ public boolean getMoreResults(int current) throws SQLException {
+ return cst.getMoreResults(current);
+ }
+
+ @Override
+ public ResultSet getGeneratedKeys() throws SQLException {
+ return cst.getGeneratedKeys();
+ }
+
+ @Override
+ public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+ return cst.executeUpdate(sql, autoGeneratedKeys);
+ }
+
+ @Override
+ public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
+ return cst.executeUpdate(sql, columnIndexes);
+ }
+
+ @Override
+ public int executeUpdate(String sql, String[] columnNames) throws SQLException {
+ return cst.executeUpdate(sql, columnNames);
+ }
+
+ @Override
+ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+ return cst.execute(sql, autoGeneratedKeys);
+ }
+
+ @Override
+ public boolean execute(String sql, int[] columnIndexes) throws SQLException {
+ return cst.execute(sql, columnIndexes);
+ }
+
+ @Override
+ public boolean execute(String sql, String[] columnNames) throws SQLException {
+ return cst.execute(sql, columnNames);
+ }
+
+ @Override
+ public int getResultSetHoldability() throws SQLException {
+ return cst.getResultSetHoldability();
+ }
+
+ @Override
+ public boolean isClosed() throws SQLException {
+ return cst.isClosed();
+ }
+
+ @Override
+ public void setPoolable(boolean poolable) throws SQLException {
+ cst.setPoolable(poolable);
+ }
+
+ @Override
+ public boolean isPoolable() throws SQLException {
+ return cst.isPoolable();
+ }
+
+ @Override
+ public void closeOnCompletion() throws SQLException {
+ cst.closeOnCompletion();
+ }
+
+ @Override
+ public boolean isCloseOnCompletion() throws SQLException {
+ return cst.isCloseOnCompletion();
+ }
+
+ @Override
+ public T unwrap(Class iface) throws SQLException {
+ return cst.unwrap(iface);
+ }
+
+ @Override
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return cst.isWrapperFor(iface);
+ }
+}
diff --git a/agent/src/main/java/com/fanruan/agent/jdbc/statement/AgentStatement.java b/agent/src/main/java/com/fanruan/agent/jdbc/statement/AgentStatement.java
index 3e64a4f..4bff6bc 100644
--- a/agent/src/main/java/com/fanruan/agent/jdbc/statement/AgentStatement.java
+++ b/agent/src/main/java/com/fanruan/agent/jdbc/statement/AgentStatement.java
@@ -4,6 +4,9 @@ import com.fanruan.agent.jdbc.resultset.AgentResultSet;
import java.sql.*;
+/**
+ * @author Yichen Dai
+ */
public class AgentStatement implements Statement {
final private Statement st;
diff --git a/agent/src/main/java/com/fanruan/cache/BeanCache.java b/agent/src/main/java/com/fanruan/cache/BeanCache.java
index de0d338..ae67152 100644
--- a/agent/src/main/java/com/fanruan/cache/BeanCache.java
+++ b/agent/src/main/java/com/fanruan/cache/BeanCache.java
@@ -31,4 +31,12 @@ public interface BeanCache {
*/
void cacheInstance(String ID, Object o);
+ /**
+ * verify whether the Instance is exit
+ * @param ID The unique num of a cache instance, It comes from the RPC request ID,
+ * which asked to create the instance.
+ * @return if it exits, true, otherwise false.
+ */
+ boolean containsInstance(String ID);
+
}
diff --git a/agent/src/main/java/com/fanruan/cache/BeanCacheImpl.java b/agent/src/main/java/com/fanruan/cache/BeanCacheImpl.java
index 0926afb..ca723ac 100644
--- a/agent/src/main/java/com/fanruan/cache/BeanCacheImpl.java
+++ b/agent/src/main/java/com/fanruan/cache/BeanCacheImpl.java
@@ -38,4 +38,9 @@ public class BeanCacheImpl implements BeanCache{
public void cacheInstance(String ID, Object o){
CACHE.put(ID, o);
}
+
+ @Override
+ public boolean containsInstance(String ID) {
+ return CACHE.containsKey(ID);
+ }
}
diff --git a/agent/src/main/java/com/fanruan/cache/Cache.java b/agent/src/main/java/com/fanruan/cache/Cache.java
index 7c03272..3b24709 100644
--- a/agent/src/main/java/com/fanruan/cache/Cache.java
+++ b/agent/src/main/java/com/fanruan/cache/Cache.java
@@ -2,6 +2,7 @@ package com.fanruan.cache;
import io.socket.client.Socket;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -37,6 +38,12 @@ public interface Cache {
*/
Socket getSocket(String dbName);
+ /**
+ * get sockets
+ * @return a list of socket
+ */
+ List getSockets();
+
/**
* register the socket of specific nameSpace/db
* @param dbName the key of cache
diff --git a/agent/src/main/java/com/fanruan/cache/CacheImpl.java b/agent/src/main/java/com/fanruan/cache/CacheImpl.java
index 817b79f..dc7fa78 100644
--- a/agent/src/main/java/com/fanruan/cache/CacheImpl.java
+++ b/agent/src/main/java/com/fanruan/cache/CacheImpl.java
@@ -2,6 +2,10 @@ package com.fanruan.cache;
import io.socket.client.Socket;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
/**
* @author Yichen Dai
* @date 2022/8/16 16:13
@@ -22,6 +26,15 @@ public class CacheImpl implements Cache{
return socket;
}
+ @Override
+ public List getSockets() {
+ List res = new ArrayList<>();
+ for(Map.Entry e : SOCKET_MAP.entrySet()){
+ res.add(e.getValue());
+ }
+ return res;
+ }
+
@Override
public void registerBeanCache(String dbName, BeanCacheImpl beanCache) {
BEAN_CACHE.put(dbName, beanCache);
diff --git a/agent/src/main/java/com/fanruan/handler/DispatcherHelper.java b/agent/src/main/java/com/fanruan/handler/DispatcherHelper.java
index 6da14a7..0e03968 100644
--- a/agent/src/main/java/com/fanruan/handler/DispatcherHelper.java
+++ b/agent/src/main/java/com/fanruan/handler/DispatcherHelper.java
@@ -30,10 +30,25 @@ public class DispatcherHelper {
"Statement",
"PreparedStatement",
"ResultSet",
+ "MetaData",
+ "Clob",
+ "Blob",
+ "Array",
+ "Struct"
};
+ public static boolean isInCacheList(Object obj){
+ if(obj == null) {
+ return false;
+ }
+ return isInCacheList(obj.getClass().getName());
+ }
+
public static boolean isInCacheList(String className){
+ if (className == null){
+ return false;
+ }
for(String s : CACHE_LIST){
if(Pattern.matches(".*" + s + ".*", className)){
return true;
@@ -43,6 +58,9 @@ public class DispatcherHelper {
}
public static boolean isWraps(Class> clz){
+ if(clz == null) {
+ return false;
+ }
return WRAPPER_CLASS_MAP.containsKey(getClassName(clz.getName()));
}
@@ -51,15 +69,11 @@ public class DispatcherHelper {
}
public static String getClassName(String fullyQualifiedClassName){
- String[] arr = fullyQualifiedClassName.split("\\.");
+ String[] arr = fullyQualifiedClassName.trim().split("\\.");
int n = arr.length;
- if(n == 0) {
- throw new RuntimeException("the class name invoked is wrong");
+ if(n < 1) {
+ throw new RuntimeException("the class's name invoked is wrong");
}
return arr[n-1];
}
-
- public static String transformName(String name){
- return name.replace("servicejdbc", "agentjdbc");
- }
}
diff --git a/agent/src/main/java/com/fanruan/handler/DispatcherImpl.java b/agent/src/main/java/com/fanruan/handler/DispatcherImpl.java
index 4d196d0..2359ce5 100644
--- a/agent/src/main/java/com/fanruan/handler/DispatcherImpl.java
+++ b/agent/src/main/java/com/fanruan/handler/DispatcherImpl.java
@@ -6,6 +6,7 @@ import com.fanruan.pojo.message.RpcRequest;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -27,8 +28,8 @@ public class DispatcherImpl implements Dispatcher{
Object res = null;
try {
res = invokeAsRequest(rpcRequest, beanCache);
- }catch (Exception e){
- RESPONSE_EMITTER_IMPL.sendError(CACHE.getSocket(dbName), rpcRequest, e);
+ }catch (Throwable t){
+ RESPONSE_EMITTER_IMPL.sendError(CACHE.getSocket(dbName), rpcRequest, t);
}
if(res != null && !DispatcherHelper.isInCacheList(res.getClass().getName())){
@@ -39,7 +40,7 @@ public class DispatcherImpl implements Dispatcher{
}
@Override
- public Object invokeAsRequest(RpcRequest rpcRequest, BeanCacheImpl beanCache) throws Exception{
+ public Object invokeAsRequest(RpcRequest rpcRequest, BeanCacheImpl beanCache) throws Throwable {
String fullName = rpcRequest.getServiceClassName();
Class> clazz = Class.forName(fullName);
String methodName = rpcRequest.getMethodName();
@@ -80,28 +81,25 @@ public class DispatcherImpl implements Dispatcher{
}
}
method = clazz.getDeclaredMethod(methodName, argTypes);
-
-
}
+ Object res = null;
- Object res = method.invoke(calledClassInstance, args);
-
- if(CLOSE_NAME.equals(methodName)){
- beanCache.removeInstances(IDToInvoke);
+ try{
+ res = method.invoke(calledClassInstance, args);
+ }catch (InvocationTargetException e){
+ throw e.getCause();
}
// Cached some instances need to be invoke later.
- // Some method return null, so determine the value of `res` before referencing it.
- if(res != null){
- String resClassName = res.getClass().getName();
- if(DispatcherHelper.isInCacheList(resClassName)) {
- beanCache.cacheInstance(rpcRequest.getID(), res);
- }
- logger.debug("invoke" + className + "-" + methodName + " and return a instance of" + res.getClass().getName());
- }else{
- logger.debug("invoke" + className + "-" + methodName + " and no return value");
+ // Some method return null
+
+ if(DispatcherHelper.isInCacheList(res)) {
+ beanCache.cacheInstance(rpcRequest.getID(), res);
}
+
+ logger.debug("invoke" + className + "-" + methodName + " and return value : " + res);
+
return res;
}
diff --git a/agent/src/main/java/com/fanruan/handler/ResponseEmitter.java b/agent/src/main/java/com/fanruan/handler/ResponseEmitter.java
index 45007b5..783b35e 100644
--- a/agent/src/main/java/com/fanruan/handler/ResponseEmitter.java
+++ b/agent/src/main/java/com/fanruan/handler/ResponseEmitter.java
@@ -20,9 +20,9 @@ public interface ResponseEmitter {
* Send failure response when error occur while handle request.
* @param socket
* @param rpcRequest
- * @param e Exception happened while handle request.
+ * @param t Exception happened while handle request.
*/
- void sendError(Socket socket, RpcRequest rpcRequest, Exception e);
+ void sendError(Socket socket, RpcRequest rpcRequest, Throwable t);
/**
* Send success response with data asked by request.
diff --git a/agent/src/main/java/com/fanruan/handler/ResponseEmitterImpl.java b/agent/src/main/java/com/fanruan/handler/ResponseEmitterImpl.java
index 56b5df0..b26edf8 100644
--- a/agent/src/main/java/com/fanruan/handler/ResponseEmitterImpl.java
+++ b/agent/src/main/java/com/fanruan/handler/ResponseEmitterImpl.java
@@ -22,11 +22,11 @@ public class ResponseEmitterImpl implements ResponseEmitter{
}
@Override
- public void sendError(Socket socket, RpcRequest rpcRequest, Exception e){
+ public void sendError(Socket socket, RpcRequest rpcRequest, Throwable t){
RpcResponse rpcResponse = new RpcResponse();
rpcResponse.setResult("Some errors happened when AgentID: " + AgentStarter.AgentID + " "
+ rpcRequest.getMethodName() + " is being invoked!" + "\n"
- + "Error Message: " + e.getMessage()
+ + "Error Message: " + t.getMessage()
+ " and check your code")
.setID(rpcRequest.getID())
.setStatus(false);
diff --git a/agent/src/main/java/com/fanruan/pojo/message/RpcRequest.java b/agent/src/main/java/com/fanruan/pojo/message/RpcRequest.java
index 0389900..152a8eb 100644
--- a/agent/src/main/java/com/fanruan/pojo/message/RpcRequest.java
+++ b/agent/src/main/java/com/fanruan/pojo/message/RpcRequest.java
@@ -10,7 +10,6 @@ import lombok.experimental.Accessors;
@Accessors(chain = true)
public class RpcRequest {
private String ID;
-// private boolean binding;
private String IDToInvoke;
private String serviceClassName;
private String methodName;
diff --git a/agent/src/test/java/HSQLTest.java b/agent/src/test/java/HSQLTest.java
index 370efd6..4e685c0 100644
--- a/agent/src/test/java/HSQLTest.java
+++ b/agent/src/test/java/HSQLTest.java
@@ -25,7 +25,7 @@ public class HSQLTest {
void getConnection() throws SQLException {
Connection conn = null;
try {
- conn = DriverManager.getConnection("jdbc:hsqldb:mem:test", "sa", "");
+ conn = DriverManager.getConnection("jdbc:hsqldb:mem:test;sql.syntax_mys=true", "sa", "");
Assertions.assertNotNull(conn, "can't get connection");
} catch (SQLException e) {
e.printStackTrace();
@@ -34,6 +34,29 @@ public class HSQLTest {
}
}
+ private static String createStoredProcedure ="CREATE PROCEDURE get_city_name(" +
+ "IN c_id INT, " +
+ "OUT city_name varchar(20)) " +
+ "READS SQL DATA " +
+ "BEGIN ATOMIC " +
+ " SELECT city.name INTO city_name FROM city WHERE id = c_id; " +
+ "END;";
+
+ @Test
+ public void test() throws SQLException {
+ Connection conn = DriverManager.getConnection("jdbc:hsqldb:mem:test;sql.syntax_mys=true", "sa", "");
+ Statement statement = conn.createStatement();
+ statement.executeUpdate("CREATE TABLE city (id INTEGER, name varchar(20)); ");
+ statement.executeUpdate("INSERT INTO city VALUES (1, '成都'), (2, '上海'); ");
+
+ statement.execute(createStoredProcedure);
+ CallableStatement callableStatement = conn.prepareCall("{call get_city_name(?, ?)}");
+ callableStatement.setInt(1, 2);
+ callableStatement.registerOutParameter(2, Types.VARCHAR);
+ callableStatement.execute();
+ System.out.println(callableStatement.getString(2));
+ }
+
/**
* test to create statement instance and prepareStatement, create table, select form table, delete from table
*/
@@ -44,7 +67,7 @@ public class HSQLTest {
PreparedStatement pst = null;
ResultSet rs = null;
try {
- conn = DriverManager.getConnection("jdbc:hsqldb:mem:test", "sa", "");
+ conn = DriverManager.getConnection("jdbc:hsqldb:mem:test;sql.syntax_mys=true", "sa", "");
st = conn.createStatement();
st.executeUpdate("DROP TABLE student IF EXISTS;");
@@ -82,6 +105,8 @@ public class HSQLTest {
Assertions.assertEquals(rs.getString("student_address"), addressStrings[num-1]);
num++;
}
+
+
} catch (Exception e) {
e.printStackTrace();
} finally {
diff --git a/agent/src/test/java/Test.java b/agent/src/test/java/Test.java
index 90179e3..61e5763 100644
--- a/agent/src/test/java/Test.java
+++ b/agent/src/test/java/Test.java
@@ -2,6 +2,8 @@ import com.fanruan.AgentStarter;
import com.fanruan.utils.DBProperties;
import io.socket.client.Socket;
+import java.util.HashMap;
+
public class Test {
@@ -27,7 +29,6 @@ public class Test {
Socket socket = AgentStarter.dispatcherImpl.CACHE.getSocket(DBProperties.HSQL[0]);
socket.connect();
-
}
}
diff --git a/agent/src/test/java/TestSuite.java b/agent/src/test/java/TestSuite.java
new file mode 100644
index 0000000..c0b293c
--- /dev/null
+++ b/agent/src/test/java/TestSuite.java
@@ -0,0 +1,14 @@
+import org.junit.platform.suite.api.IncludeClassNamePatterns;
+import org.junit.platform.suite.api.SelectPackages;
+import org.junit.platform.suite.api.Suite;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/23 15:04
+ */
+
+@SelectPackages({"com.fanruan"})
+@Suite
+@IncludeClassNamePatterns(".*Test.*")
+public class TestSuite {
+}
diff --git a/agent/src/test/java/com/fanruan/cache/BeanCacheImplTest.java b/agent/src/test/java/com/fanruan/cache/BeanCacheImplTest.java
new file mode 100644
index 0000000..2853fdc
--- /dev/null
+++ b/agent/src/test/java/com/fanruan/cache/BeanCacheImplTest.java
@@ -0,0 +1,24 @@
+package com.fanruan.cache;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/22 19:54
+ */
+class BeanCacheImplTest {
+
+ @Test
+ void getCachedInstances() {
+ }
+
+ @Test
+ void removeInstances() {
+ }
+
+ @Test
+ void cacheInstance() {
+ }
+}
\ No newline at end of file
diff --git a/agent/src/test/java/com/fanruan/cache/CacheImplTest.java b/agent/src/test/java/com/fanruan/cache/CacheImplTest.java
new file mode 100644
index 0000000..48f62d2
--- /dev/null
+++ b/agent/src/test/java/com/fanruan/cache/CacheImplTest.java
@@ -0,0 +1,44 @@
+package com.fanruan.cache;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/22 19:54
+ */
+class CacheImplTest {
+
+ @Test
+ void registerSocket() {
+ }
+
+ @Test
+ void getSocket() {
+ }
+
+ @Test
+ void registerBeanCache() {
+ }
+
+ @Test
+ void getBeanCache() {
+ }
+
+ @Test
+ void testRegisterSocket() {
+ }
+
+ @Test
+ void testGetSocket() {
+ }
+
+ @Test
+ void testRegisterBeanCache() {
+ }
+
+ @Test
+ void testGetBeanCache() {
+ }
+}
\ No newline at end of file
diff --git a/agent/src/test/java/com/fanruan/handler/DispatcherHelperTest.java b/agent/src/test/java/com/fanruan/handler/DispatcherHelperTest.java
new file mode 100644
index 0000000..d9e8940
--- /dev/null
+++ b/agent/src/test/java/com/fanruan/handler/DispatcherHelperTest.java
@@ -0,0 +1,71 @@
+package com.fanruan.handler;
+
+import com.fanruan.agent.jdbc.driver.AgentDriver;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/22 15:07
+ */
+class DispatcherHelperTest{
+
+
+
+ @Test
+ void isInCacheList() {
+ Assertions.assertTrue(DispatcherHelper.isInCacheList(new AgentDriver()));
+
+ Assertions.assertTrue(DispatcherHelper.isInCacheList("com.fanruan.agent.jdbc.agentDriver"));
+ Assertions.assertTrue(DispatcherHelper.isInCacheList("com.fanruan.agent.jdbc.agentConnection"));
+ Assertions.assertTrue(DispatcherHelper.isInCacheList("com.fanruan.agent.jdbc.agentStatement"));
+ Assertions.assertTrue(DispatcherHelper.isInCacheList("com.fanruan.agent.jdbc.agentPrepareStatement"));
+ Assertions.assertTrue(DispatcherHelper.isInCacheList("com.fanruan.agent.jdbc.agentResultSet"));
+
+ Assertions.assertFalse(DispatcherHelper.isInCacheList("java.lang.String"));
+ Assertions.assertFalse(DispatcherHelper.isInCacheList("java.lang.Integer"));
+ Assertions.assertFalse(DispatcherHelper.isInCacheList("com.fanruan.agent.cache.BeanCache"));
+ Assertions.assertFalse(DispatcherHelper.isInCacheList(""));
+ Assertions.assertFalse(DispatcherHelper.isInCacheList(null));
+
+ }
+
+ @Test
+ void isWraps() {
+ Assertions.assertTrue(DispatcherHelper.isWraps(java.lang.Byte.class));
+ Assertions.assertTrue(DispatcherHelper.isWraps(java.lang.Character.class));
+ Assertions.assertTrue(DispatcherHelper.isWraps(java.lang.Short.class));
+ Assertions.assertTrue(DispatcherHelper.isWraps(java.lang.Integer.class));
+ Assertions.assertTrue(DispatcherHelper.isWraps(java.lang.Long.class));
+ Assertions.assertTrue(DispatcherHelper.isWraps(java.lang.Boolean.class));
+ Assertions.assertTrue(DispatcherHelper.isWraps(java.lang.Float.class));
+ Assertions.assertTrue(DispatcherHelper.isWraps(java.lang.Double.class));
+
+ Assertions.assertFalse(DispatcherHelper.isWraps(Integer.TYPE));
+ Assertions.assertFalse(DispatcherHelper.isWraps(java.lang.String.class));
+ Assertions.assertFalse(DispatcherHelper.isWraps(null));
+ }
+
+ @Test
+ void castToPrimitiveClass() {
+ Assertions.assertEquals(Byte.TYPE, DispatcherHelper.castToPrimitiveClass(Byte.class));
+ Assertions.assertEquals(Character.TYPE, DispatcherHelper.castToPrimitiveClass(Character.class));
+ Assertions.assertEquals(Short.TYPE, DispatcherHelper.castToPrimitiveClass(Short.class));
+ Assertions.assertEquals(Integer.TYPE, DispatcherHelper.castToPrimitiveClass(Integer.class));
+ Assertions.assertEquals(Long.TYPE, DispatcherHelper.castToPrimitiveClass(Long.class));
+ Assertions.assertEquals(Boolean.TYPE, DispatcherHelper.castToPrimitiveClass(Boolean.class));
+ Assertions.assertEquals(Float.TYPE, DispatcherHelper.castToPrimitiveClass(Float.class));
+ Assertions.assertEquals(Double.TYPE, DispatcherHelper.castToPrimitiveClass(Double.class));
+ }
+
+ @Test
+ void getClassName() {
+ Assertions.assertEquals("agentDriver", DispatcherHelper.getClassName("com.fanruan.agent.jdbc.agentDriver"));
+ Assertions.assertEquals("agentDriver", DispatcherHelper.getClassName(" com.fanruan.agent.jdbc.agentDriver "));
+ Assertions.assertEquals("fakeName", DispatcherHelper.getClassName("fakeName"));
+ Assertions.assertEquals("", DispatcherHelper.getClassName(""));
+ Assertions.assertThrows(RuntimeException.class, () -> DispatcherHelper.getClassName(null));
+ }
+}
\ No newline at end of file
diff --git a/agent/src/test/java/com/fanruan/handler/DispatcherImplTest.java b/agent/src/test/java/com/fanruan/handler/DispatcherImplTest.java
new file mode 100644
index 0000000..314bca9
--- /dev/null
+++ b/agent/src/test/java/com/fanruan/handler/DispatcherImplTest.java
@@ -0,0 +1,27 @@
+package com.fanruan.handler;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/22 14:47
+ */
+class DispatcherImplTest {
+
+ @Test
+ void doDispatch() {
+
+ }
+
+ @Test
+ void invokeAsRequest() {
+ }
+
+ @Test
+ void testDoDispatch() {
+ }
+
+ @Test
+ void testInvokeAsRequest() {
+ }
+}
\ No newline at end of file
diff --git a/pic/project structure.jpg b/pic/project structure.jpg
index b95ca74..e69de29 100644
Binary files a/pic/project structure.jpg and b/pic/project structure.jpg differ
diff --git a/service/pom.xml b/service/pom.xml
index 91a4083..c963489 100644
--- a/service/pom.xml
+++ b/service/pom.xml
@@ -69,11 +69,20 @@
1.18.22
-
+
org.junit.jupiter
junit-jupiter-engine
- 5.4.0
+ 5.9.0
+ test
+
+
+
+
+
+ org.junit.platform
+ junit-platform-suite-engine
+ 1.9.0
test
diff --git a/service/src/main/java/com/fanruan/ServerStater.java b/service/src/main/java/com/fanruan/ServerStater.java
index 724d483..4f4e099 100644
--- a/service/src/main/java/com/fanruan/ServerStater.java
+++ b/service/src/main/java/com/fanruan/ServerStater.java
@@ -58,6 +58,10 @@ public class ServerStater{
}
+ public void shutDown(){
+ server.stop();
+ }
+
private void addEvent(SocketIONamespace nameSpace){
logger.debug("配置事件监听");
nameSpace.addConnectListener(client -> {
@@ -180,7 +184,7 @@ public class ServerStater{
client.disconnect();
}
- // 缓存连接
+ // remove client
ClientCache.deleteClient(agentID, dbName);
logger.info("agentID: " + agentID + "连接关闭");
logger.info("agentID: " + agentID + "连接已删除");
diff --git a/service/src/main/java/com/fanruan/pojo/message/RpcRequest.java b/service/src/main/java/com/fanruan/pojo/message/RpcRequest.java
index 0990d43..ab38997 100644
--- a/service/src/main/java/com/fanruan/pojo/message/RpcRequest.java
+++ b/service/src/main/java/com/fanruan/pojo/message/RpcRequest.java
@@ -14,7 +14,6 @@ public class RpcRequest {
* In the project, they are Drive( MyDriver ), Connection( MyConnection ), Statement( MyStatement ),
* PreparedStatement( MyPreparedStatement ), ResultSet( MyResult ).
*/
-// private boolean binding;
private String ID;
private String IDToInvoke;
private String serviceClassName;
diff --git a/service/src/test/java/AutoStarter.java b/service/src/test/java/AutoStarter.java
deleted file mode 100644
index fee30c7..0000000
--- a/service/src/test/java/AutoStarter.java
+++ /dev/null
@@ -1,22 +0,0 @@
-import com.fanruan.ServerStater;
-import com.fanruan.utils.DBProperties;
-
-/**
- * @author Yichen Dai
- * @date 2022/8/18 9:54
- */
-public class AutoStarter {
-
- static {
- String[][] DBs = new String[][]{
- DBProperties.HSQL,
- };
- new ServerStater(DBs);
-
- try {
- Class.forName("com.fanruan.service.jdbc.driver.ServiceDriver");
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- }
-}
diff --git a/service/src/test/java/ServiceTest.java b/service/src/test/java/ServiceTest.java
index d395f64..0b04e9e 100644
--- a/service/src/test/java/ServiceTest.java
+++ b/service/src/test/java/ServiceTest.java
@@ -15,7 +15,7 @@ import java.util.concurrent.FutureTask;
* @author Yichen Dai
* @date 2022/8/18 9:49
*/
-public class ServiceTest extends AutoStarter{
+public class ServiceTest {
@BeforeEach
void listen() throws ExecutionException, InterruptedException {
diff --git a/service/src/test/java/TestSuite.java b/service/src/test/java/TestSuite.java
new file mode 100644
index 0000000..e5fe975
--- /dev/null
+++ b/service/src/test/java/TestSuite.java
@@ -0,0 +1,13 @@
+import org.junit.platform.suite.api.IncludeClassNamePatterns;
+import org.junit.platform.suite.api.SelectPackages;
+import org.junit.platform.suite.api.Suite;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/23 15:30
+ */
+@SelectPackages({"com.fanruan"})
+@IncludeClassNamePatterns(".*Test.*")
+@Suite
+public class TestSuite {
+}
diff --git a/test/pom.xml b/test/pom.xml
index 86cf656..0d5e5b6 100644
--- a/test/pom.xml
+++ b/test/pom.xml
@@ -29,14 +29,25 @@
1.0-SNAPSHOT
-
+
org.junit.jupiter
junit-jupiter-engine
- 5.4.0
+ 5.9.0
test
+
+
+
+ org.junit.platform
+ junit-platform-suite-engine
+ 1.9.0
+ test
+
+
+
+
org.apache.logging.log4j
log4j-api
diff --git a/test/src/test/java/TestSuite.java b/test/src/test/java/TestSuite.java
new file mode 100644
index 0000000..3948c3b
--- /dev/null
+++ b/test/src/test/java/TestSuite.java
@@ -0,0 +1,16 @@
+import org.junit.platform.suite.api.IncludeClassNamePatterns;
+import org.junit.platform.suite.api.SelectPackages;
+import org.junit.platform.suite.api.Suite;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/23 14:39
+ */
+
+@SelectPackages({"com.fanruan"})
+@IncludeClassNamePatterns(".*Test.*")
+@Suite
+public class TestSuite {
+}
+
+
diff --git a/test/src/test/java/TestUtil.java b/test/src/test/java/TestUtil.java
deleted file mode 100644
index a49a0db..0000000
--- a/test/src/test/java/TestUtil.java
+++ /dev/null
@@ -1,170 +0,0 @@
-
-import com.fanruan.AgentStarter;
-import com.fanruan.ServerStater;
-
-import com.fanruan.service.jdbc.driver.ServiceDriver;
-import com.fanruan.proxy.ProxyFactory;
-import com.fanruan.utils.DBProperties;
-import org.junit.jupiter.api.*;
-
-import java.sql.*;
-import java.util.Properties;
-
-/**
- * @author Yichen Dai
- * @date 2022/8/18 15:27
- */
-
-public class TestUtil {
-
- static Connection conn = null;
- static Statement st = null;
- static PreparedStatement pst = null;
- static ResultSet rs = null;
-
- static void configService(){
- String[][] DBs = new String[][]{
- DBProperties.HSQL,
- };
- new ServerStater(DBs);
- }
-
- static void configAgent(){
- String[][] DBs = new String[][]{
- DBProperties.HSQL,
- };
- new AgentStarter(DBs);
- }
-
- @BeforeAll
- static void autoConfig(){
- configService();
- configAgent();
- try {
- // 等待socket连接
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- @Test
- void testConnect() throws SQLException {
- // 建立连接
- Properties info = new Properties();
- info.setProperty("user", "sa");
- info.setProperty("password", "");
- info.setProperty("agentID", "1001");
- info.setProperty("agentDBName", DBProperties.HSQL[0]);
-
- Driver driver = (ServiceDriver) ProxyFactory.getProxy(ServiceDriver.class, null);
- conn = driver.connect("jdbc:hsqldb:mem:test", info);
- }
-
-
-
-
- @Test
- void testCreateTable() throws SQLException {
- testConnect();
- // 创建 statement
- st = conn.createStatement();
-
- // 创建表
- int num = st.executeUpdate("DROP TABLE student IF EXISTS;");
-
- Assertions.assertEquals(0, num);
-
-
- num = st.executeUpdate("CREATE TABLE student (" +
- "student_id INTEGER GENERATED BY DEFAULT AS IDENTITY " +
- "(START WITH 1, INCREMENT BY 1) NOT NULL," +
- "student_name VARCHAR(100) NOT NULL," +
- "student_address VARCHAR(100) NOT NULL," +
- "PRIMARY KEY (student_id)" +
- ");");
-
- Assertions.assertEquals(0, num);
- }
-
- @Test
- void testInsert() throws SQLException {
- testCreateTable();
- // 插入数据
- int num = st.executeUpdate("INSERT INTO student VALUES" +
- "(1, '张三', '上海')," +
- "(2, '李四', '北京')," +
- "(3, '王五', '成都');");
-
- Assertions.assertEquals(3, num);
- }
-
- @Test
- void testUpdate() throws SQLException {
- testInsert();
- // 预查询语句 删除指定 ID
- pst = conn.prepareStatement("UPDATE student" +
- " SET student_name = '李华', student_address = '杭州'"+
- "WHERE student_id = ?");
-
- Assertions.assertNotNull(pst);
-
- pst.setInt(1, 1);
-
- int num = pst.executeUpdate();
-
- Assertions.assertEquals(1, num);
- }
-
- @Test
- void testDelete() throws SQLException {
- testInsert();
- // 预查询语句 删除指定 ID
- pst = conn.prepareStatement("delete from student where student_id = ?");
-
- Assertions.assertNotNull(pst);
-
- pst.setInt(1, 1);
-
- int num = pst.executeUpdate();
-
- Assertions.assertEquals(1, num);
- }
-
- @Test
- void testSelect() throws SQLException {
- testInsert();
- rs = st.executeQuery("select * from student");
-
- String[] nameStrings = new String[]{"张三", "李四", "王五"};
- String[] addressStrings = new String[]{"上海", "北京", "成都"};
-
- // 结果集断言
- int num = 1;
- while(rs.next()) {
- Assertions.assertEquals(rs.getInt("student_id"), num);
- Assertions.assertEquals(rs.getString("student_name"), nameStrings[num-1]);
- Assertions.assertEquals(rs.getString("student_address"), addressStrings[num-1]);
- num++;
- }
- }
-
- @AfterAll
- static void close() throws SQLException {
- if(rs!= null){
- rs.close();
- }
-
- if(pst != null){
- pst.close();
- }
-
- if(st != null){
- st.close();
- }
-
- if(conn != null){
- conn.close();
- }
- }
-}
diff --git a/test/src/test/java/com/fanruan/AbstractDriverTest.java b/test/src/test/java/com/fanruan/AbstractDriverTest.java
new file mode 100644
index 0000000..80fab3a
--- /dev/null
+++ b/test/src/test/java/com/fanruan/AbstractDriverTest.java
@@ -0,0 +1,58 @@
+package com.fanruan;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/23 15:49
+ */
+
+import com.fanruan.cache.ClientCache;
+import com.fanruan.proxy.ProxyFactory;
+import com.fanruan.service.jdbc.driver.ServiceDriver;
+import com.fanruan.utils.DBProperties;
+
+import java.sql.*;
+import java.util.Properties;
+
+/** Base test class with common constants, data structures and methods */
+public class AbstractDriverTest {
+ static final Properties info = new Properties();
+
+ static final String[][] dbNameAndDriver = new String[][]{
+ DBProperties.HSQL
+ };
+
+ static final ServerStater server = new ServerStater(dbNameAndDriver);
+ static final AgentStarter agent = new AgentStarter(dbNameAndDriver);
+
+
+ static {
+ info.setProperty("user", "sa");
+ info.setProperty("password", "");
+ info.setProperty("agentID", "1001");
+ info.setProperty("agentDBName", DBProperties.HSQL[0]);
+ }
+
+ static void openSocket(){
+ while(ClientCache.getClient(
+ info.getProperty("agentID"),
+ info.getProperty("agentDBName"))
+ == null){
+ }
+ }
+
+ void shutDown(){
+ agent.shutDown();
+ server.shutDown();
+ }
+
+ /**
+ * Gets a connection
+ * @return Connection a database connection
+ * @throws SQLException raised if any error occurs
+ */
+ public static Connection getConnection() throws SQLException {
+ Driver driver = (ServiceDriver) ProxyFactory.getProxy(ServiceDriver.class, null);
+ Connection conn = driver.connect("jdbc:hsqldb:mem:test;sql.syntax_mys=true", info);
+ return conn;
+ }
+}
diff --git a/test/src/test/java/com/fanruan/AgentCallableStatementTest.java b/test/src/test/java/com/fanruan/AgentCallableStatementTest.java
new file mode 100644
index 0000000..51b6fb5
--- /dev/null
+++ b/test/src/test/java/com/fanruan/AgentCallableStatementTest.java
@@ -0,0 +1,1171 @@
+package com.fanruan;
+
+import com.fanruan.cache.BeanCacheImpl;
+import com.fanruan.handler.DispatcherImpl;
+import com.fanruan.pojo.message.RpcRequest;
+import com.fanruan.pojo.message.RpcResponse;
+import com.fanruan.proxy.interceptor.InterceptorUtils;
+import com.fanruan.service.jdbc.ServiceBlob;
+import com.fanruan.service.jdbc.statement.ServiceCallableStatement;
+import com.fanruan.utils.Commons;
+import org.junit.jupiter.api.*;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import java.io.*;
+import java.lang.reflect.InvocationTargetException;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.sql.Date;
+import java.util.*;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/24 10:22
+ */
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+public class AgentCallableStatementTest extends BaseJDBCTest{
+
+ private Connection conn = null;
+ private Statement statement = null;
+ private CallableStatement callableStatement = null;
+ private Properties properties = null;
+
+ private static String createStoredProcedure = "CREATE PROCEDURE get_city_name(" +
+ "IN c_id INT, " +
+ "OUT city_name varchar(20)) " +
+ "READS SQL DATA " +
+ "BEGIN ATOMIC " +
+ " SELECT city.name INTO city_name FROM city WHERE id = c_id; " +
+ "END;";
+
+ private static String callProcedure =
+ "{call get_city_name(?, ?) }";
+
+ private static String deleteStoredProcedure =
+ "DROP PROCEDURE IF EXISTS cnt_num;";
+
+ @BeforeAll
+ public void setUp() throws SQLException{
+ openSocket();
+ conn = getConnection();
+ statement = conn.createStatement();
+ statement.executeUpdate("CREATE TABLE city (id INTEGER, name varchar(20)); ");
+ statement.executeUpdate("INSERT INTO city VALUES (1, '成都'), (2, '上海'); ");
+ statement.execute(deleteStoredProcedure);
+ statement.execute(createStoredProcedure);
+ }
+
+ @Test
+ @Order(1)
+ public void testPrepareCall() throws SQLException{
+ callableStatement = conn.prepareCall(callProcedure);
+ ParameterMetaData parameterMetaData = callableStatement.getParameterMetaData();
+ int num = parameterMetaData.getParameterCount();
+ Assertions.assertEquals(2, num);
+ Assertions.assertEquals(Types.INTEGER, parameterMetaData.getParameterType(1));
+ Assertions.assertEquals("INTEGER", parameterMetaData.getParameterTypeName(1));
+
+ callableStatement.setInt(1, 2);
+ callableStatement.registerOutParameter(2, Types.VARCHAR);
+ callableStatement.execute();
+ Assertions.assertEquals("上海", callableStatement.getString(2));
+
+
+ }
+
+ @Test
+ @Order(2)
+ void testMethods() throws SQLException {
+ ServiceCallableStatement cstm = (ServiceCallableStatement) this.callableStatement;
+ String IDtoInvoke = cstm.getID();
+
+ DispatcherImpl dispatcher = agent.dispatcherImpl;
+ BeanCacheImpl beanCache = dispatcher.CACHE.getBeanCache(dbName);
+ ServiceCallableStatement cstm2 = (ServiceCallableStatement) ProxyFactoryIT.getProxy(ServiceCallableStatement.class, map);
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.registerOutParameter(1, Types.INTEGER);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.registerOutParameter(1, Types.INTEGER, 1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.registerOutParameter(1, Types.INTEGER, "int");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.registerOutParameter("param_name", Types.INTEGER);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.registerOutParameter("param_name", Types.INTEGER, 1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.registerOutParameter("param_name", Types.INTEGER, "int");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getArray("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getArray(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getBigDecimal("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getBigDecimal(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getBlob("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getBlob(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getBoolean("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getBoolean(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getByte("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getByte(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getCharacterStream("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getCharacterStream(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getClob("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getClob(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getDate("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getDate(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getDouble("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getDouble(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getFloat("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getFloat(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getInt("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getInt(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getLong("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getLong(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getNCharacterStream("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getNCharacterStream(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getNClob("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getNClob(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setNClob("param_name", new FakeNClob());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setNClob("param_name", new FakeReader(), 1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setNClob("param_name", new FakeReader());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getNString("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getNString(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getObject("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getObject(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getObject(1, String.class);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getRef("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getRef(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getRowId("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getRowId(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getShort("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getShort(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getSQLXML("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getSQLXML(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getString("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getString(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getTime("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getTime(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getTimestamp(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getTimestamp("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getURL("param_name");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getURL(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getString(1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setBigDecimal("param_name", BigDecimal.ONE);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setBoolean("param_name", true);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setByte("param_name", (byte) 6);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setBytes("param_name", "bytes".getBytes());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setBytes(1, "bytes".getBytes());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setDate("param_name", Date.valueOf("2019-07-07"));
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setDouble("param_name", 3.0);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setFloat("param_name", 3.0f);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setInt("param_name", 3);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setLong("param_name", 3L);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setNString("param_name", "test");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setNull("param_name", Types.NULL);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setNull("param_name", Types.NULL, "null");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setObject("param_name", new Object());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setObject("param_name", new Object(), Types.JAVA_OBJECT);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setObject("param_name", new Object(), Types.JAVA_OBJECT, 2);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setShort("param_name", (short) 1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setString("param_name", "test");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setTime("param_name", new Time(50));
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setTimestamp("param_name", new Timestamp(50), Calendar.getInstance());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setTimestamp(
+ "param_name", new Timestamp(50), Calendar.getInstance());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setTimestamp("param_name", new Timestamp(50));
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setURL(1, new URL("http://localhost:8888"));
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setAsciiStream("param_name", new FakeInputStream());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setAsciiStream("param_name", new FakeInputStream(), 1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setAsciiStream("param_name", new FakeInputStream(), 5213L);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setBinaryStream("param_name", new FakeInputStream());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setBinaryStream("param_name", new FakeInputStream(), 1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setBinaryStream("param_name", new FakeInputStream(), 5213L);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setBlob("param_name", new FakeInputStream());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setBlob("param_name", new FakeInputStream(), 1L);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setBlob("param_name", new ServiceBlob());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setCharacterStream("param_name", new FakeReader());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setCharacterStream("param_name", new FakeReader(), 1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setCharacterStream("param_name", new FakeReader(), 1L);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setClob("param_name", new FakeReader());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setClob("param_name", new FakeReader(), 1);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setClob("param_name", new FakeNClob());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setClob("param_name", new FakeNClob());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setDate(
+ "param_name", Date.valueOf("2019-07-07"), Calendar.getInstance());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getTime("param_name", Calendar.getInstance());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getTime(1, Calendar.getInstance());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getObject("param_name", String.class);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getObject("param_name", new HashMap<>());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getDate(1, Calendar.getInstance());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.getDate("param_name", Calendar.getInstance());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setRowId("param_name", new FakeRowId());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setSQLXML("param_name", new FakeSQLXML());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ cstm2.setSQLXML("param_name", new FakeSQLXML());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(
+ request,
+ beanCache);
+ }
+ );
+
+
+ }
+
+}
diff --git a/test/src/test/java/com/fanruan/BaseJDBCTest.java b/test/src/test/java/com/fanruan/BaseJDBCTest.java
new file mode 100644
index 0000000..564074c
--- /dev/null
+++ b/test/src/test/java/com/fanruan/BaseJDBCTest.java
@@ -0,0 +1,432 @@
+package com.fanruan;
+
+import com.fanruan.annotation.RemoteClass;
+import com.fanruan.pojo.message.RpcRequest;
+import com.fanruan.service.jdbc.AbstractBind;
+import com.fanruan.utils.Commons;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import java.io.*;
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/23 15:47
+ */
+
+
+public class BaseJDBCTest extends AbstractDriverTest{
+ final String dbName = "hsql";
+ final Map map = new HashMap(1);
+
+ int getSizeOfResultSet(ResultSet rs) throws SQLException {
+ int count = 0;
+ while (rs.next()) {
+ count++;
+ }
+ return count;
+ }
+
+ List getInfoBySQL(String sqlCmd) throws SQLException {
+ Connection con = getConnection();
+ Statement st = con.createStatement();
+ List result = new ArrayList<>();
+ ResultSet rs = st.executeQuery(sqlCmd);
+ while (rs.next()) {
+ result.add(rs.getString(1));
+ }
+ return result;
+ }
+
+ public RpcRequest createRequest(AbstractBind bind, String methodName, Object[] args, Class>[] argTypes) {
+ RpcRequest request = new RpcRequest();
+
+ request.setID(Commons.getID())
+ .setIDToInvoke(bind.getID())
+ .setMethodName(methodName)
+ .setArgs(args)
+ .setArgTypes(argTypes);
+
+ Class clazz = bind.getClass();
+
+ if(clazz.isAnnotationPresent(RemoteClass.class)){
+ RemoteClass annotation = (RemoteClass) clazz.getAnnotation(RemoteClass.class);
+ request.setServiceClassName(annotation.remoteClassName());
+ }else{
+ request.setServiceClassName(clazz.getName());
+ }
+ return request;
+ }
+
+ public boolean isEqualRequest(RpcRequest r1, RpcRequest r2){
+ String[] s1 = new String[]{
+ r1.getID(),
+ r1.getIDToInvoke(),
+ r1.getMethodName(),
+ r1.getServiceClassName()
+ };
+
+ String[] s2 = new String[]{
+ r2.getID(),
+ r2.getIDToInvoke(),
+ r2.getMethodName(),
+ r2.getServiceClassName()
+ };
+
+ if(isNotEqualStringArray(s1, s2)){
+ return false;
+ }
+
+ Object[] o1 = r1.getArgs();
+ Object[] o2 = r2.getArgs();
+ int o1_len = o1.length;
+ int o2_len = o2.length;
+ String[] o1_sa = new String[o1_len];
+ String[] o2_sa = new String[o2_len];
+
+ for(int i=0; i[] c1 = r1.getArgTypes();
+ Class>[] c2 = r2.getArgTypes();
+ int c1_len = c1.length;
+ int c2_len = c2.length;
+ String[] c1_sa = new String[c1_len];
+ String[] c2_sa = new String[c2_len];
+
+ for(int i=0; i T getSource(Class sourceClass) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public T setResult(Class resultClass) throws SQLException {
+ return null;
+ }
+}
+
+class FakeBlob implements Blob {
+ @Override
+ public long length() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public byte[] getBytes(long pos, int length) throws SQLException {
+ return new byte[0];
+ }
+
+ @Override
+ public InputStream getBinaryStream() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public long position(byte[] pattern, long start) throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public long position(Blob pattern, long start) throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int setBytes(long pos, byte[] bytes) throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public OutputStream setBinaryStream(long pos) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public void truncate(long len) throws SQLException {}
+
+ @Override
+ public void free() throws SQLException {}
+
+ @Override
+ public InputStream getBinaryStream(long pos, long length) throws SQLException {
+ return null;
+ }
+}
+
+class FakeArray implements Array {
+ @Override
+ public String getBaseTypeName() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public int getBaseType() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public Object getArray() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public Object getArray(Map> map) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public Object getArray(long index, int count) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public Object getArray(long index, int count, Map> map) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public ResultSet getResultSet() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public ResultSet getResultSet(Map> map) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public ResultSet getResultSet(long index, int count) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public ResultSet getResultSet(long index, int count, Map> map)
+ throws SQLException {
+ return null;
+ }
+
+ @Override
+ public void free() throws SQLException {}
+}
+
+class FakeRowId implements RowId {
+ @Override
+ public byte[] getBytes() {
+ return new byte[0];
+ }
+}
+
+class FakeNClob implements NClob {
+ @Override
+ public long length() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public String getSubString(long pos, int length) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public Reader getCharacterStream() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public InputStream getAsciiStream() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public long position(String searchstr, long start) throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public long position(Clob searchstr, long start) throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int setString(long pos, String str) throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public int setString(long pos, String str, int offset, int len) throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public OutputStream setAsciiStream(long pos) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public Writer setCharacterStream(long pos) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public void truncate(long len) throws SQLException {}
+
+ @Override
+ public void free() throws SQLException {}
+
+ @Override
+ public Reader getCharacterStream(long pos, long length) throws SQLException {
+ return null;
+ }
+}
+
+class FakeRef implements Ref {
+
+ @Override
+ public String getBaseTypeName() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public Object getObject(Map> map) throws SQLException {
+ return null;
+ }
+
+ @Override
+ public Object getObject() throws SQLException {
+ return null;
+ }
+
+ @Override
+ public void setObject(Object value) throws SQLException {}
+}
+
+class FakeSavepoint implements Savepoint{
+
+ @Override
+ public int getSavepointId() throws SQLException {
+ return 0;
+ }
+
+ @Override
+ public String getSavepointName() throws SQLException {
+ return null;
+ }
+}
diff --git a/test/src/test/java/com/fanruan/ConnectionTest.java b/test/src/test/java/com/fanruan/ConnectionTest.java
new file mode 100644
index 0000000..a4707fc
--- /dev/null
+++ b/test/src/test/java/com/fanruan/ConnectionTest.java
@@ -0,0 +1,314 @@
+package com.fanruan;
+
+import com.fanruan.cache.BeanCacheImpl;
+import com.fanruan.exception.NotImplementedException;
+import com.fanruan.handler.DispatcherImpl;
+import com.fanruan.pojo.message.RpcRequest;
+import com.fanruan.service.jdbc.connection.ServiceConnection;
+import org.junit.jupiter.api.*;
+
+import java.sql.*;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Properties;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/30 10:23
+ */
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+public class ConnectionTest extends BaseJDBCTest{
+
+ Connection connection = null;
+ String IDtoInvoke = "";
+ BeanCacheImpl beanCache = null;
+ DispatcherImpl dispatcher = null;
+ ServiceConnection serviceConnection = null;
+
+ @BeforeAll
+ public void setUp() throws SQLException {
+ openSocket();
+ connection = getConnection();
+ ServiceConnection conn = (ServiceConnection) connection;
+ IDtoInvoke = conn.getID();
+ dispatcher = agent.dispatcherImpl;
+ beanCache = dispatcher.CACHE.getBeanCache(dbName);
+ serviceConnection = (ServiceConnection) ProxyFactoryIT.getProxy(ServiceConnection.class, map);
+ }
+
+ @Test
+ public void testSetCatalogSchema() throws Throwable{
+ String db = connection.getCatalog();
+ String schema = connection.getSchema();
+ connection.setCatalog(db);
+ connection.setSchema("PUBLIC");
+
+ // get the current schema
+ ResultSet rst = connection.createStatement().executeQuery("SELECT * " +
+ "FROM INFORMATION_SCHEMA.TABLES");
+ Assertions.assertTrue(rst.next());
+ Assertions.assertEquals("PUBLIC", rst.getString(1));
+ Assertions.assertEquals(db, connection.getCatalog());
+ Assertions.assertEquals("PUBLIC", connection.getSchema());
+
+ // get the current schema
+ connection.setSchema(schema);
+ rst = connection.createStatement().executeQuery("SELECT * " +
+ "FROM INFORMATION_SCHEMA.TABLES");
+ Assertions.assertTrue(rst.next());
+ Assertions.assertEquals(schema, rst.getString(1));
+ rst.close();
+ }
+
+ @Test
+ public void testConnection() throws Throwable {
+ Properties property = connection.getClientInfo();
+ Assertions.assertNull(property);
+ Properties clientInfo = new Properties();
+ clientInfo.setProperty("name", "Peter");
+ clientInfo.setProperty("description", "HSQLDB JDBC");
+
+ Assertions.assertThrows(SQLClientInfoException.class, () -> {
+ serviceConnection.setClientInfo("name", "peter");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(request, beanCache);
+ });
+
+ Assertions.assertThrows(SQLClientInfoException.class, () -> {
+ serviceConnection.setClientInfo(clientInfo);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(request, beanCache);
+ });
+ }
+
+ @Test
+ public void testNetworkTimeout() throws SQLException {
+ int millis = connection.getNetworkTimeout();
+ Assertions.assertEquals(0, millis);
+ Assertions.assertThrows(SQLFeatureNotSupportedException.class, () -> {
+ serviceConnection.setNetworkTimeout(null, 200);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(request, beanCache);
+ });
+ }
+
+ @Test
+ public void testAbort() throws SQLException {
+ Assertions.assertThrows(SQLException.class, () -> {
+ serviceConnection.abort(null);
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(request, beanCache);
+ });
+ }
+
+ @Test
+ public void testClose() throws SQLException {
+ Connection conn = getConnection();
+ Assertions.assertFalse(conn.isClosed());
+ conn.close();
+ Assertions.assertTrue(conn.isClosed());
+ }
+
+ @Test
+ public void testHoldability() throws Throwable {
+ connection.setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT);
+ Assertions.assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, connection.getHoldability());
+ }
+
+ @Test
+ public void testIsValid() throws Throwable {
+ Assertions.assertTrue(connection.isValid(10));
+ }
+
+ @Test
+ public void testUnwrapper() throws SQLException {
+ boolean canUnwrap = connection.isWrapperFor(Connection.class);
+ Assertions.assertTrue(canUnwrap);
+ Assertions.assertThrows(NotImplementedException.class,
+ () -> connection.unwrap(null));
+ }
+
+ @Test
+ public void testNativeSQL() throws SQLException {
+ Assertions.assertEquals("select 1", connection.nativeSQL("select 1"));
+ }
+
+ @Test
+ public void testTypeMap() throws Throwable {
+ Assertions.assertEquals(Collections.emptyMap(), connection.getTypeMap());
+ Assertions.assertThrows(SQLException.class, () -> {
+ serviceConnection.setTypeMap(new HashMap<>());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(request, beanCache);
+ });
+ }
+
+ @Test
+ public void setReadOnly() throws SQLException {
+ Assertions.assertFalse(connection.isReadOnly());
+ connection.setReadOnly(true);
+ Assertions.assertTrue(connection.isReadOnly());
+ }
+
+ @Test
+ public void setTransactionIsolation() throws SQLException {
+ Connection conn = getConnection();
+ Assertions.assertEquals(Connection.TRANSACTION_READ_COMMITTED ,conn.getTransactionIsolation());
+ conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
+ Assertions.assertEquals(Connection.TRANSACTION_SERIALIZABLE, conn.getTransactionIsolation());
+ closeSQLObjects(conn);
+ }
+
+ @Test
+ public void testGetWarning() throws SQLException {
+ connection.clearWarnings();
+ Assertions.assertNull(connection.getWarnings());
+ }
+
+ @Test
+ public void testCreateStatement() throws SQLException {
+ Statement st1 = connection.createStatement(
+ ResultSet.TYPE_SCROLL_INSENSITIVE,
+ ResultSet.TYPE_FORWARD_ONLY);
+ Statement st2 = connection.createStatement(
+ ResultSet.TYPE_SCROLL_INSENSITIVE,
+ ResultSet.TYPE_FORWARD_ONLY,
+ ResultSet.CLOSE_CURSORS_AT_COMMIT
+ );
+
+ closeSQLObjects(st1, st2);
+ }
+
+ @Test
+ void testPrepareStatement() throws SQLException {
+ PreparedStatement pst1 = connection.prepareStatement(
+ "select 1",
+ ResultSet.TYPE_SCROLL_INSENSITIVE,
+ ResultSet.TYPE_FORWARD_ONLY
+ );
+
+ PreparedStatement pst2 = connection.prepareStatement(
+ "select 1",
+ ResultSet.TYPE_SCROLL_INSENSITIVE,
+ ResultSet.TYPE_FORWARD_ONLY,
+ ResultSet.CLOSE_CURSORS_AT_COMMIT
+ );
+
+ PreparedStatement pst3 = connection.prepareStatement(
+ "select 2",
+ Statement.NO_GENERATED_KEYS
+ );
+
+ PreparedStatement pst4 = connection.prepareStatement(
+ "select 2",
+ new int[]{0}
+ );
+
+ PreparedStatement pst5 = connection.prepareStatement(
+ "select 2",
+ new String[]{"column_name"}
+ );
+
+ closeSQLObjects(pst1, pst2, pst3, pst4, pst5);
+ }
+
+ @Test
+ void testCallableStatement() throws SQLException {
+ Statement statement = connection.createStatement();
+
+ statement.executeUpdate("CREATE TABLE city (id INTEGER, name varchar(20)); ");
+ statement.executeUpdate("INSERT INTO city VALUES (1, '成都'), (2, '上海'); ");
+
+ CallableStatement cst1 = connection.prepareCall(
+ "CREATE PROCEDURE get_city_name(" +
+ "IN c_id INT, " +
+ "OUT city_name varchar(20)) " +
+ "READS SQL DATA " +
+ "BEGIN ATOMIC " +
+ " SELECT city.name INTO city_name FROM city WHERE id = c_id; " +
+ "END;",
+ ResultSet.TYPE_SCROLL_INSENSITIVE,
+ ResultSet.TYPE_FORWARD_ONLY
+ );
+
+ CallableStatement cst2 = connection.prepareCall(
+ "CREATE PROCEDURE get_city_name(" +
+ "IN c_id INT, " +
+ "OUT city_name varchar(20)) " +
+ "READS SQL DATA " +
+ "BEGIN ATOMIC " +
+ " SELECT city.name INTO city_name FROM city WHERE id = c_id; " +
+ "END;",
+ ResultSet.TYPE_SCROLL_INSENSITIVE,
+ ResultSet.TYPE_FORWARD_ONLY,
+ ResultSet.CLOSE_CURSORS_AT_COMMIT
+ );
+
+ closeSQLObjects(cst1, cst2);
+ }
+
+ @Test
+ void testSavePoint() throws SQLException {
+ Assertions.assertThrows(SQLException.class, () -> {
+ serviceConnection.setSavepoint();
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(request, beanCache);
+ });
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ serviceConnection.setSavepoint("savePoint");
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(request, beanCache);
+ });
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ serviceConnection.rollback(new FakeSavepoint());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(request, beanCache);
+ });
+
+ Assertions.assertThrows(SQLException.class, () -> {
+ serviceConnection.releaseSavepoint(new FakeSavepoint());
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(request, beanCache);
+ });
+ }
+
+ @Test
+ void testCreateArrayOf() throws SQLException {
+ Array array = connection.createArrayOf("DOUBLE", new Double[]{0.1, 0.2});
+ }
+
+ @Test
+ void testCreateStruct() throws SQLException{
+ Assertions.assertThrows(SQLException.class, () -> {
+ serviceConnection.createStruct( "java.lang.String", new String[]{"hello"});
+ RpcRequest request = map.get(null);
+ request.setIDToInvoke(IDtoInvoke);
+ dispatcher.invokeAsRequest(request, beanCache);
+ });
+ }
+
+ @Test
+ void testAutoCommit() throws SQLException {
+ Connection conn = getConnection();
+ Assertions.assertTrue(conn.getAutoCommit());
+ conn.setAutoCommit(false);
+ Assertions.assertFalse(conn.getAutoCommit());
+ }
+
+ @Test
+ void testGetMetaData() throws SQLException {
+ DatabaseMetaData metaData = connection.getMetaData();
+ }
+}
diff --git a/test/src/test/java/com/fanruan/DatabaseMetaDataTest.java b/test/src/test/java/com/fanruan/DatabaseMetaDataTest.java
new file mode 100644
index 0000000..7423153
--- /dev/null
+++ b/test/src/test/java/com/fanruan/DatabaseMetaDataTest.java
@@ -0,0 +1,21 @@
+package com.fanruan;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/31 18:18
+ */
+public class DatabaseMetaDataTest extends BaseJDBCTest{
+ @Test
+ public void testGetConnection() throws SQLException {
+ Connection conn = getConnection();
+ DatabaseMetaData metaData = conn.getMetaData();
+ Assertions.assertEquals(conn, metaData.getConnection());
+ }
+}
diff --git a/test/src/test/java/com/fanruan/InterceptorIT.java b/test/src/test/java/com/fanruan/InterceptorIT.java
new file mode 100644
index 0000000..5e3eca6
--- /dev/null
+++ b/test/src/test/java/com/fanruan/InterceptorIT.java
@@ -0,0 +1,38 @@
+package com.fanruan;
+
+import com.fanruan.pojo.message.RpcRequest;
+import com.fanruan.proxy.interceptor.InterceptorUtils;
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/29 11:11
+ */
+public class InterceptorIT implements MethodInterceptor {
+ Class> clazz;
+ Map map;
+
+
+ InterceptorIT(Class> clazz, Map map){
+ this.clazz = clazz;
+ this.map = map;
+ }
+
+ @Override
+ public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
+ if(InterceptorUtils.isNotImplemented(method)
+ || InterceptorUtils.isLocalMethod(method)){
+ return methodProxy.invokeSuper(o, objects);
+ }
+
+ RpcRequest request = InterceptorUtils.generateRequest(clazz, o, method, objects);
+ map.put(null, request);
+
+ return methodProxy.invokeSuper(o, objects);
+ }
+}
diff --git a/test/src/test/java/com/fanruan/ProxyFactoryIT.java b/test/src/test/java/com/fanruan/ProxyFactoryIT.java
new file mode 100644
index 0000000..f78cf83
--- /dev/null
+++ b/test/src/test/java/com/fanruan/ProxyFactoryIT.java
@@ -0,0 +1,23 @@
+package com.fanruan;
+
+import com.fanruan.pojo.message.RpcRequest;
+import com.fanruan.proxy.interceptor.Interceptor;
+import net.sf.cglib.proxy.Enhancer;
+
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/29 11:15
+ */
+public class ProxyFactoryIT {
+
+ public static Object getProxy(Class> clazz, Map map){
+ final Enhancer enhancer = new Enhancer();
+ enhancer.setClassLoader(clazz.getClassLoader());
+ enhancer.setSuperclass(clazz);
+ enhancer.setCallback(new InterceptorIT(clazz, map));
+ return enhancer.create();
+ }
+}
diff --git a/test/src/test/java/com/fanruan/TestUtil.java b/test/src/test/java/com/fanruan/TestUtil.java
new file mode 100644
index 0000000..fcf4ead
--- /dev/null
+++ b/test/src/test/java/com/fanruan/TestUtil.java
@@ -0,0 +1,183 @@
+package com.fanruan;
+
+import org.junit.jupiter.api.*;
+
+import java.sql.*;
+
+
+/**
+ * @author Yichen Dai
+ * @date 2022/8/18 15:27
+ */
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+@DisplayName("jdbc操作")
+public class TestUtil extends BaseJDBCTest{
+
+ private Connection conn = null;
+ private Statement st = null;
+ private PreparedStatement pst = null;
+
+
+ @BeforeAll
+ void setup(){
+ openSocket();
+ }
+
+ @Test
+ @Order(1)
+ void testConnect() throws SQLException {
+ conn = getConnection();
+ }
+
+ @Test
+ @Order(2)
+ void testCreateTable1() throws SQLException {
+ // 创建 statement
+ st = conn.createStatement();
+
+ // 创建表
+ int num = st.executeUpdate("DROP TABLE student IF EXISTS;");
+
+ Assertions.assertEquals(0, num);
+
+
+ num = st.executeUpdate("CREATE TABLE student (" +
+ "student_id INTEGER GENERATED BY DEFAULT AS IDENTITY " +
+ "(START WITH 1, INCREMENT BY 1) NOT NULL," +
+ "student_name VARCHAR(100) NOT NULL," +
+ "student_address VARCHAR(100) NOT NULL," +
+ "PRIMARY KEY (student_id)" +
+ ");");
+
+ Assertions.assertEquals(0, num);
+ }
+
+ @Test
+ @Order(3)
+ void testCreateTable2() throws SQLException {
+ // 创建表
+ int num = st.executeUpdate("DROP TABLE student_score IF EXISTS;");
+
+ Assertions.assertEquals(0, num);
+
+
+ num = st.executeUpdate("CREATE TABLE score (" +
+ "student_id int(10) PRIMARY KEY NOT NULL," +
+ "score int(10) NOT NULL" +
+ ");"
+ );
+
+ Assertions.assertEquals(0, num);
+ }
+
+ @Test
+ @Order(4)
+ void testInsert1() throws SQLException {
+ // 插入数据
+ int num = st.executeUpdate("INSERT INTO student VALUES" +
+ "(1, '张三', '上海')," +
+ "(2, '李四', '北京')," +
+ "(3, '王五', '成都');");
+
+ Assertions.assertEquals(3, num);
+ }
+
+ @Test
+ @Order(5)
+ void testInsert2() throws SQLException {
+ // 插入数据
+ int num = st.executeUpdate("INSERT INTO score VALUES" +
+ "(1, 645)," +
+ "(2, 627)," +
+ "(3, 591);");
+
+ Assertions.assertEquals(3, num);
+ }
+
+ @Test
+ @Order(6)
+ void testUpdate() throws SQLException {
+ // 预查询语句 删除指定 ID
+ pst = conn.prepareStatement("UPDATE student" +
+ " SET student_name = '李华', student_address = '杭州'"+
+ "WHERE student_id = ?");
+
+ Assertions.assertNotNull(pst);
+
+ pst.setInt(1, 1);
+
+ int num = pst.executeUpdate();
+
+ Assertions.assertEquals(1, num);
+ }
+
+ @Test
+ @Order(7)
+ void testDelete() throws SQLException {
+ // 预查询语句 删除指定 ID
+ pst = conn.prepareStatement("delete from student where student_id = ?");
+
+ Assertions.assertNotNull(pst);
+
+ pst.setInt(1, 3);
+
+ int num = pst.executeUpdate();
+
+ Assertions.assertEquals(1, num);
+ }
+
+ @Test
+ @Order(8)
+ void testSelect() throws SQLException {
+ ResultSet rs = st.executeQuery("select * from student;");
+ Assertions.assertEquals(2, getSizeOfResultSet(rs));
+ closeSQLObjects(rs);
+ }
+
+ @Test
+ @Order(9)
+ void testSubSelect() throws SQLException {
+ // 插入数据
+ ResultSet rs = st.executeQuery(
+ "SELECT student_name FROM student " +
+ "WHERE student_id IN " +
+ "(SELECT student_id " +
+ "FROM score " +
+ "WHERE score > 600);"
+ );
+ Assertions.assertEquals(2, getSizeOfResultSet(rs));
+ closeSQLObjects(rs);
+ }
+
+ @Test
+ @Order(10)
+ void testJoin() throws SQLException {
+ // 插入数据
+ ResultSet rs = st.executeQuery(
+ "SELECT A.student_name " +
+ "FROM student A JOIN score B " +
+ "ON A.student_id = B.student_id " +
+ "WHERE score > 600;"
+ );
+
+ Assertions.assertEquals(2, getSizeOfResultSet(rs));
+ closeSQLObjects(rs);
+ }
+
+ @Test
+ @Order(10)
+ void testErrorQuery() throws SQLException {
+ // 插入数据
+ ResultSet rs = st.executeQuery("SELECT * FROM TEACHER;");
+ Assertions.assertFalse(rs.next());
+ closeSQLObjects(rs);
+ }
+
+ @AfterAll
+ void closeObject() throws SQLException {
+ closeSQLObjects(conn, st, pst);
+ }
+}
+