diff --git a/agent/src/main/java/com/fanruan/agent/jdbc/AgentDataBaseMetaData.java b/agent/src/main/java/com/fanruan/agent/jdbc/AgentDataBaseMetaData.java index d9ff58b..b07e7d3 100644 --- a/agent/src/main/java/com/fanruan/agent/jdbc/AgentDataBaseMetaData.java +++ b/agent/src/main/java/com/fanruan/agent/jdbc/AgentDataBaseMetaData.java @@ -1,5 +1,7 @@ package com.fanruan.agent.jdbc; +import com.fanruan.agent.jdbc.resultset.AgentResultSet; + import java.sql.*; /** @@ -55,7 +57,7 @@ public class AgentDataBaseMetaData implements DatabaseMetaData { @Override public boolean nullsAreSortedAtEnd() throws SQLException { - return metaData.nullsAreSortedAtStart(); + return metaData.nullsAreSortedAtEnd(); } @Override @@ -115,7 +117,7 @@ public class AgentDataBaseMetaData implements DatabaseMetaData { @Override public boolean storesMixedCaseIdentifiers() throws SQLException { - return metaData.supportsMixedCaseIdentifiers(); + return metaData.storesMixedCaseIdentifiers(); } @Override @@ -135,7 +137,7 @@ public class AgentDataBaseMetaData implements DatabaseMetaData { @Override public boolean storesMixedCaseQuotedIdentifiers() throws SQLException { - return metaData.supportsMixedCaseQuotedIdentifiers(); + return metaData.storesMixedCaseQuotedIdentifiers(); } @Override @@ -205,7 +207,7 @@ public class AgentDataBaseMetaData implements DatabaseMetaData { @Override public boolean supportsConvert(int fromType, int toType) throws SQLException { - return metaData.supportsConvert(); + return metaData.supportsConvert(fromType, toType); } @Override @@ -605,87 +607,87 @@ public class AgentDataBaseMetaData implements DatabaseMetaData { @Override public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException { - return metaData.getProcedures(catalog, schemaPattern, procedureNamePattern); + return new AgentResultSet(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); + return new AgentResultSet(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); + return new AgentResultSet(metaData.getTables(catalog, schemaPattern, tableNamePattern, types)); } @Override public ResultSet getSchemas() throws SQLException { - return metaData.getSchemas(); + return new AgentResultSet(metaData.getSchemas()); } @Override public ResultSet getCatalogs() throws SQLException { - return metaData.getCatalogs(); + return new AgentResultSet(metaData.getCatalogs()); } @Override public ResultSet getTableTypes() throws SQLException { - return metaData.getTableTypes(); + return new AgentResultSet(metaData.getTableTypes()); } @Override public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException { - return metaData.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern); + return new AgentResultSet(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); + return new AgentResultSet(metaData.getColumnPrivileges(catalog, schema, table, columnNamePattern)); } @Override public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { - return metaData.getTablePrivileges(catalog, schemaPattern, tableNamePattern); + return new AgentResultSet(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); + return new AgentResultSet(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); + return new AgentResultSet(metaData.getVersionColumns(catalog, schema, table)); } @Override public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException { - return metaData.getPrimaryKeys(catalog, schema, table); + return new AgentResultSet(metaData.getPrimaryKeys(catalog, schema, table)); } @Override public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException { - return metaData.getImportedKeys(catalog, schema, table); + return new AgentResultSet(metaData.getImportedKeys(catalog, schema, table)); } @Override public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException { - return metaData.getExportedKeys(catalog, schema, table); + return new AgentResultSet(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); + return new AgentResultSet(metaData.getCrossReference(parentCatalog, parentSchema, parentTable, foreignCatalog, foreignSchema, foreignTable)); } @Override public ResultSet getTypeInfo() throws SQLException { - return metaData.getTypeInfo(); + return new AgentResultSet(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); + return new AgentResultSet(metaData.getIndexInfo(catalog, schema, table, unique, approximate)); } @Override @@ -750,7 +752,7 @@ public class AgentDataBaseMetaData implements DatabaseMetaData { @Override public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException { - return metaData.getUDTs(catalog, schemaPattern, typeNamePattern, types); + return new AgentResultSet(metaData.getUDTs(catalog, schemaPattern, typeNamePattern, types)); } @Override @@ -780,17 +782,17 @@ public class AgentDataBaseMetaData implements DatabaseMetaData { @Override public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) throws SQLException { - return metaData.getSuperTypes(catalog, schemaPattern, typeNamePattern); + return new AgentResultSet(metaData.getSuperTypes(catalog, schemaPattern, typeNamePattern)); } @Override public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { - return metaData.getSuperTypes(catalog, schemaPattern, tableNamePattern); + return new AgentResultSet(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); + return new AgentResultSet(metaData.getAttributes(catalog, schemaPattern, typeNamePattern, attributeNamePattern)); } @Override @@ -845,7 +847,7 @@ public class AgentDataBaseMetaData implements DatabaseMetaData { @Override public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException { - return metaData.getSchemas(catalog, schemaPattern); + return new AgentResultSet(metaData.getSchemas(catalog, schemaPattern)); } @Override @@ -860,22 +862,22 @@ public class AgentDataBaseMetaData implements DatabaseMetaData { @Override public ResultSet getClientInfoProperties() throws SQLException { - return metaData.getClientInfoProperties(); + return new AgentResultSet(metaData.getClientInfoProperties()); } @Override public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) throws SQLException { - return metaData.getFunctions(catalog, schemaPattern, functionNamePattern); + return new AgentResultSet(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); + return new AgentResultSet(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); + return new AgentResultSet(metaData.getPseudoColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern)); } @Override diff --git a/agent/src/main/java/com/fanruan/agent/jdbc/AgentResultMetaData.java b/agent/src/main/java/com/fanruan/agent/jdbc/AgentResultMetaData.java new file mode 100644 index 0000000..8432d1a --- /dev/null +++ b/agent/src/main/java/com/fanruan/agent/jdbc/AgentResultMetaData.java @@ -0,0 +1,131 @@ +package com.fanruan.agent.jdbc; + +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +/** + * @author Yichen Dai + * @date 2022/9/1 14:45 + */ +public class AgentResultMetaData implements ResultSetMetaData { + private ResultSetMetaData metaData; + + AgentResultMetaData(ResultSetMetaData metaData){ + this.metaData = metaData; + } + + @Override + public int getColumnCount() throws SQLException { + return metaData.getColumnCount(); + } + + @Override + public boolean isAutoIncrement(int column) throws SQLException { + return metaData.isAutoIncrement(column); + } + + @Override + public boolean isCaseSensitive(int column) throws SQLException { + return metaData.isCaseSensitive(column); + } + + @Override + public boolean isSearchable(int column) throws SQLException { + return metaData.isSearchable(column); + } + + @Override + public boolean isCurrency(int column) throws SQLException { + return metaData.isCurrency(column); + } + + @Override + public int isNullable(int column) throws SQLException { + return metaData.isNullable(column); + } + + @Override + public boolean isSigned(int column) throws SQLException { + return metaData.isSigned(column); + } + + @Override + public int getColumnDisplaySize(int column) throws SQLException { + return metaData.getColumnDisplaySize(column); + } + + @Override + public String getColumnLabel(int column) throws SQLException { + return metaData.getColumnLabel(column); + } + + @Override + public String getColumnName(int column) throws SQLException { + return metaData.getColumnName(column); + } + + @Override + public String getSchemaName(int column) throws SQLException { + return metaData.getSchemaName(column); + } + + @Override + public int getPrecision(int column) throws SQLException { + return metaData.getPrecision(column); + } + + @Override + public int getScale(int column) throws SQLException { + return metaData.getScale(column); + } + + @Override + public String getTableName(int column) throws SQLException { + return metaData.getTableName(column); + } + + @Override + public String getCatalogName(int column) throws SQLException { + return metaData.getCatalogName(column); + } + + @Override + public int getColumnType(int column) throws SQLException { + return metaData.getColumnType(column); + } + + @Override + public String getColumnTypeName(int column) throws SQLException { + return metaData.getColumnTypeName(column); + } + + @Override + public boolean isReadOnly(int column) throws SQLException { + return metaData.isReadOnly(column); + } + + @Override + public boolean isWritable(int column) throws SQLException { + return metaData.isWritable(column); + } + + @Override + public boolean isDefinitelyWritable(int column) throws SQLException { + return metaData.isDefinitelyWritable(column); + } + + @Override + public String getColumnClassName(int column) throws SQLException { + return metaData.getColumnClassName(column); + } + + @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/service/src/main/java/com/fanruan/service/jdbc/ServiceDataBaseMetaData.java b/service/src/main/java/com/fanruan/service/jdbc/ServiceDatabaseMetaData.java similarity index 83% rename from service/src/main/java/com/fanruan/service/jdbc/ServiceDataBaseMetaData.java rename to service/src/main/java/com/fanruan/service/jdbc/ServiceDatabaseMetaData.java index cc05524..d7e0456 100644 --- a/service/src/main/java/com/fanruan/service/jdbc/ServiceDataBaseMetaData.java +++ b/service/src/main/java/com/fanruan/service/jdbc/ServiceDatabaseMetaData.java @@ -2,17 +2,27 @@ package com.fanruan.service.jdbc; import com.fanruan.annotation.LocalMethod; +import com.fanruan.annotation.NotImplemented; import com.fanruan.annotation.RemoteClass; +import com.fanruan.proxy.ProxyFactory; import com.fanruan.service.jdbc.driver.ServiceDriver; +import com.fanruan.service.jdbc.resultset.ServiceResultSet; import java.sql.*; import java.util.Map; +import java.util.Set; /** * @author Yichen Dai */ @RemoteClass(remoteClassName = "com.fanruan.agent.jdbc.AgentDataBaseMetaData") -public class ServiceDataBaseMetaData extends BasedBind implements java.sql.DatabaseMetaData{ +public class ServiceDatabaseMetaData extends BasedBind implements java.sql.DatabaseMetaData{ + private Connection conn; + + @LocalMethod + public void setConn(Connection conn) { + this.conn = conn; + } @Override public boolean allProceduresAreCallable() throws SQLException { @@ -61,32 +71,32 @@ public class ServiceDataBaseMetaData extends BasedBind implements java.sql.Datab @Override public String getDatabaseProductName() throws SQLException { - return "agent server 1.0.0"; + return null; } @Override public String getDatabaseProductVersion() throws SQLException { - return "1.0.0"; + return null; } @Override public String getDriverName() throws SQLException { - return "myDriver for Agent"; + return null; } @Override public String getDriverVersion() throws SQLException { - return "1.0.0"; + return null; } @Override public int getDriverMajorVersion() { - return ServiceDriver.DRIVER_VERSION_MAJOR; + return 0; } @Override public int getDriverMinorVersion() { - return ServiceDriver.DRIVER_VERSION_MINOR; + return 0; } @Override @@ -606,87 +616,121 @@ public class ServiceDataBaseMetaData extends BasedBind implements java.sql.Datab @Override public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); + return rs; } @Override public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); + return rs; } @Override public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); + return rs; } @Override public ResultSet getSchemas() throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); + return rs; } @Override public ResultSet getCatalogs() throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); + return rs; } @Override public ResultSet getTableTypes() throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); + return rs; } @Override public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); + return rs; } @Override public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); + return rs; } @Override public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); + return rs; } @Override public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); + return rs; } @Override public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); + return rs; } @Override public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); + return rs; } @Override public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); + return rs; } @Override public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); + return rs; } @Override public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); + return rs; } @Override public ResultSet getTypeInfo() throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); + return rs; } @Override public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); + return rs; } @Override @@ -751,13 +795,14 @@ public class ServiceDataBaseMetaData extends BasedBind implements java.sql.Datab @Override public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + return rs; } @LocalMethod @Override public Connection getConnection() throws SQLException { - return null; + return this.conn; } @Override @@ -782,17 +827,20 @@ public class ServiceDataBaseMetaData extends BasedBind implements java.sql.Datab @Override public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + return rs; } @Override public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + return rs; } @Override public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + return rs; } @Override @@ -847,7 +895,8 @@ public class ServiceDataBaseMetaData extends BasedBind implements java.sql.Datab @Override public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + return rs; } @Override @@ -862,22 +911,26 @@ public class ServiceDataBaseMetaData extends BasedBind implements java.sql.Datab @Override public ResultSet getClientInfoProperties() throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + return rs; } @Override public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + return rs; } @Override public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + return rs; } @Override public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException { - return null; + ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + return rs; } @Override @@ -885,9 +938,11 @@ public class ServiceDataBaseMetaData extends BasedBind implements java.sql.Datab return false; } + @NotImplemented + @LocalMethod @Override public T unwrap(Class iface) throws SQLException { - return null; + throw new SQLException("Not Implemented"); } @Override diff --git a/service/src/main/java/com/fanruan/service/jdbc/ServiceResultSetMetaData.java b/service/src/main/java/com/fanruan/service/jdbc/ServiceResultSetMetaData.java new file mode 100644 index 0000000..859bfde --- /dev/null +++ b/service/src/main/java/com/fanruan/service/jdbc/ServiceResultSetMetaData.java @@ -0,0 +1,129 @@ +package com.fanruan.service.jdbc; + +import com.fanruan.annotation.RemoteClass; + +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +/** + * @author Yichen Dai + * @date 2022/9/1 14:44 + */ +@RemoteClass(remoteClassName = "com.fanruan.agent.jdbc.AgentResultSetMetaData") +public class ServiceResultSetMetaData extends BasedBind implements ResultSetMetaData { + + @Override + public int getColumnCount() throws SQLException { + return 0; + } + + @Override + public boolean isAutoIncrement(int column) throws SQLException { + return false; + } + + @Override + public boolean isCaseSensitive(int column) throws SQLException { + return false; + } + + @Override + public boolean isSearchable(int column) throws SQLException { + return false; + } + + @Override + public boolean isCurrency(int column) throws SQLException { + return false; + } + + @Override + public int isNullable(int column) throws SQLException { + return 0; + } + + @Override + public boolean isSigned(int column) throws SQLException { + return false; + } + + @Override + public int getColumnDisplaySize(int column) throws SQLException { + return 0; + } + + @Override + public String getColumnLabel(int column) throws SQLException { + return null; + } + + @Override + public String getColumnName(int column) throws SQLException { + return null; + } + + @Override + public String getSchemaName(int column) throws SQLException { + return null; + } + + @Override + public int getPrecision(int column) throws SQLException { + return 0; + } + + @Override + public int getScale(int column) throws SQLException { + return 0; + } + + @Override + public String getTableName(int column) throws SQLException { + return null; + } + + @Override + public String getCatalogName(int column) throws SQLException { + return null; + } + + @Override + public int getColumnType(int column) throws SQLException { + return 0; + } + + @Override + public String getColumnTypeName(int column) throws SQLException { + return null; + } + + @Override + public boolean isReadOnly(int column) throws SQLException { + return false; + } + + @Override + public boolean isWritable(int column) throws SQLException { + return false; + } + + @Override + public boolean isDefinitelyWritable(int column) throws SQLException { + return false; + } + + @Override + public String getColumnClassName(int column) throws SQLException { + return null; + } + + @Override + public T unwrap(Class iface) throws SQLException { + return null; + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return false; + } +} diff --git a/service/src/main/java/com/fanruan/service/jdbc/connection/ServiceConnection.java b/service/src/main/java/com/fanruan/service/jdbc/connection/ServiceConnection.java index 890c981..1d18488 100644 --- a/service/src/main/java/com/fanruan/service/jdbc/connection/ServiceConnection.java +++ b/service/src/main/java/com/fanruan/service/jdbc/connection/ServiceConnection.java @@ -1,13 +1,10 @@ package com.fanruan.service.jdbc.connection; -import com.corundumstudio.socketio.SocketIOClient; import com.fanruan.annotation.NotImplemented; import com.fanruan.annotation.RemoteClass; -import com.fanruan.cache.ClientCache; -import com.fanruan.service.jdbc.AbstractBind; import com.fanruan.service.jdbc.BasedBind; -import com.fanruan.service.jdbc.ServiceDataBaseMetaData; +import com.fanruan.service.jdbc.ServiceDatabaseMetaData; import com.fanruan.service.jdbc.statement.ServiceCallableStatement; import com.fanruan.service.jdbc.statement.ServicePreparedStatement; import com.fanruan.service.jdbc.statement.ServiceStatement; @@ -84,7 +81,10 @@ public class ServiceConnection extends BasedBind implements Connection { @Override public DatabaseMetaData getMetaData() throws SQLException { - return (DatabaseMetaData) ProxyFactory.getProxy(ServiceDataBaseMetaData.class, info); + ServiceDatabaseMetaData metaData = (ServiceDatabaseMetaData) ProxyFactory.getProxy(ServiceDatabaseMetaData.class, info); + metaData.setConn(this); + metaData.setInfo(info); + return metaData; } @Override diff --git a/service/src/main/java/com/fanruan/service/jdbc/resultset/ServiceResultSet.java b/service/src/main/java/com/fanruan/service/jdbc/resultset/ServiceResultSet.java index 104212b..0e99ed2 100644 --- a/service/src/main/java/com/fanruan/service/jdbc/resultset/ServiceResultSet.java +++ b/service/src/main/java/com/fanruan/service/jdbc/resultset/ServiceResultSet.java @@ -2,8 +2,9 @@ package com.fanruan.service.jdbc.resultset; import com.fanruan.annotation.RemoteClass; -import com.fanruan.service.jdbc.AbstractBind; +import com.fanruan.proxy.ProxyFactory; import com.fanruan.service.jdbc.BasedBind; +import com.fanruan.service.jdbc.ServiceResultSetMetaData; import java.io.InputStream; import java.io.Reader; @@ -211,7 +212,8 @@ public class ServiceResultSet extends BasedBind implements ResultSet { @Override public ResultSetMetaData getMetaData() throws SQLException { - return null; + ServiceResultSetMetaData metaData = (ServiceResultSetMetaData) ProxyFactory.getProxy(ServiceResultSetMetaData.class, info); + return metaData; } @Override diff --git a/service/src/main/java/com/fanruan/service/jdbc/statement/ServiceCallableStatement.java b/service/src/main/java/com/fanruan/service/jdbc/statement/ServiceCallableStatement.java index 7d63b66..8ff96af 100644 --- a/service/src/main/java/com/fanruan/service/jdbc/statement/ServiceCallableStatement.java +++ b/service/src/main/java/com/fanruan/service/jdbc/statement/ServiceCallableStatement.java @@ -594,6 +594,7 @@ public class ServiceCallableStatement extends BasedBind implements CallableState @Override public ResultSet executeQuery() throws SQLException { ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); return rs; } @@ -870,6 +871,7 @@ public class ServiceCallableStatement extends BasedBind implements CallableState @Override public ResultSet executeQuery(String sql) throws SQLException { ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); return rs; } diff --git a/service/src/main/java/com/fanruan/service/jdbc/statement/ServicePreparedStatement.java b/service/src/main/java/com/fanruan/service/jdbc/statement/ServicePreparedStatement.java index 9574881..0a2ca29 100644 --- a/service/src/main/java/com/fanruan/service/jdbc/statement/ServicePreparedStatement.java +++ b/service/src/main/java/com/fanruan/service/jdbc/statement/ServicePreparedStatement.java @@ -22,10 +22,8 @@ public class ServicePreparedStatement extends BasedBind implements PreparedState @Override public ResultSet executeQuery() throws SQLException { - if(isClosed()) { - throw new SQLException("This Statement is closed."); - } ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); return rs; } diff --git a/service/src/main/java/com/fanruan/service/jdbc/statement/ServiceStatement.java b/service/src/main/java/com/fanruan/service/jdbc/statement/ServiceStatement.java index d841237..7c41620 100644 --- a/service/src/main/java/com/fanruan/service/jdbc/statement/ServiceStatement.java +++ b/service/src/main/java/com/fanruan/service/jdbc/statement/ServiceStatement.java @@ -17,10 +17,8 @@ public class ServiceStatement extends BasedBind implements Statement { @Override public ResultSet executeQuery(String sql) throws SQLException { - if(isClosed()) { - throw new SQLException("This Statement is closed."); - } ServiceResultSet rs = (ServiceResultSet) ProxyFactory.getProxy(ServiceResultSet.class, info); + rs.setInfo(info); return rs; } diff --git a/test/src/test/java/TestSuite.java b/test/src/test/java/TestSuite.java index 3948c3b..57aae4c 100644 --- a/test/src/test/java/TestSuite.java +++ b/test/src/test/java/TestSuite.java @@ -14,3 +14,4 @@ public class TestSuite { } + diff --git a/test/src/test/java/com/fanruan/AbstractDriverTest.java b/test/src/test/java/com/fanruan/AbstractDriverTest.java index 80fab3a..0fc7150 100644 --- a/test/src/test/java/com/fanruan/AbstractDriverTest.java +++ b/test/src/test/java/com/fanruan/AbstractDriverTest.java @@ -52,7 +52,7 @@ public class AbstractDriverTest { */ 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); + Connection conn = driver.connect("jdbc:hsqldb:mem:test;sql.syntax_mys=true", info); return conn; } } diff --git a/test/src/test/java/com/fanruan/DatabaseMetaDataTest.java b/test/src/test/java/com/fanruan/DatabaseMetaDataTest.java index 7423153..1be3d53 100644 --- a/test/src/test/java/com/fanruan/DatabaseMetaDataTest.java +++ b/test/src/test/java/com/fanruan/DatabaseMetaDataTest.java @@ -1,21 +1,717 @@ package com.fanruan; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.*; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.SQLException; +import java.sql.*; /** * @author Yichen Dai * @date 2022/8/31 18:18 */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class DatabaseMetaDataTest extends BaseJDBCTest{ + + Connection conn = null; + DatabaseMetaData metaData = null; + + @BeforeAll + public void setUp() throws SQLException { + openSocket(); + this.conn = getConnection(); + this.metaData = conn.getMetaData(); + } + @Test public void testGetConnection() throws SQLException { - Connection conn = getConnection(); - DatabaseMetaData metaData = conn.getMetaData(); Assertions.assertEquals(conn, metaData.getConnection()); } + + @Test + public void testNotImplemented() throws SQLException{ + Assertions.assertThrows(SQLException.class, () -> metaData.unwrap(null)); + } + + @Test + public void testDatabaseAndDriverInfo() throws SQLException { + + Assertions.assertEquals(4, metaData.getJDBCMajorVersion()); + Assertions.assertEquals(2, metaData.getJDBCMinorVersion()); + + Assertions.assertEquals(2, metaData.getDatabaseMajorVersion()); + Assertions.assertEquals(6, metaData.getDatabaseMinorVersion()); + + + Assertions.assertEquals("HSQL Database Engine", metaData.getDatabaseProductName()); + Assertions.assertEquals("2.6.0", metaData.getDatabaseProductVersion()); + Assertions.assertEquals("HSQL Database Engine Driver", metaData.getDriverName()); + Assertions.assertEquals("2.6.0", metaData.getDriverVersion()); + + Assertions.assertEquals(2, metaData.getDriverMajorVersion()); + Assertions.assertEquals(6, metaData.getDriverMinorVersion()); + + // HSQLDB returns sqlStateSQL under JDBC4 which is equivalent to JDBC3 value of sqlStateSQL99. + Assertions.assertEquals(DatabaseMetaData.sqlStateSQL ,metaData.getSQLStateType()); + + Assertions.assertEquals(RowIdLifetime.ROWID_UNSUPPORTED, metaData.getRowIdLifetime().ROWID_UNSUPPORTED); + + } + + @Test + public void testGetCatalogs() throws SQLException { + Assertions.assertEquals(".", metaData.getCatalogSeparator()); + Assertions.assertEquals("CATALOG", metaData.getCatalogTerm()); + + // From 2.0, HSQLDB supports catalog names where allowed by the standard; + // this method always returns true. + Assertions.assertTrue(metaData.supportsCatalogsInDataManipulation()); + + // From 2.0, HSQLDB supports catalog names where allowed by the standard; + // this method always returns true. + Assertions.assertTrue(metaData.supportsCatalogsInProcedureCalls()); + + // From 2.0, HSQLDB supports catalog names where allowed by the standard; + // this method always returns true. + Assertions.assertTrue(metaData.supportsCatalogsInTableDefinitions()); + + // From 2.0, HSQLDB supports catalog names where allowed by the standard; + // this method always returns true. + Assertions.assertTrue(metaData.supportsCatalogsInIndexDefinitions()); + + // From 2.0, HSQLDB supports catalog names where allowed by the standard; + // this method always returns true. + Assertions.assertTrue(metaData.supportsCatalogsInPrivilegeDefinitions()); + + // When allowed, a catalog appears at the start of a fully qualified table name; + // this method always returns true. + Assertions.assertTrue(metaData.isCatalogAtStart()); + + ResultSet rs = metaData.getCatalogs(); + rs.next(); + Assertions.assertEquals("PUBLIC", rs.getString(1)); + + closeSQLObjects(rs); + } + + @Test + void getTable() throws SQLException{ + ResultSet rs = metaData.getTableTypes(); + + // GLOBAL TEMPORARY、SYSTEM TABLE、TABLE、VIEW + Assertions.assertEquals(4, getSizeOfResultSet(rs)); + + closeSQLObjects(rs); + } + + @Test + void testGetSchema() throws SQLException { + ResultSet rs = metaData.getSchemas(); + + // From 2.0, HSQLDB supports schemas where allowed by the standard; + // this method always returns true. + Assertions.assertTrue(metaData.supportsSchemasInDataManipulation()); + + // From 2.0, HSQLDB supports schemas where allowed by the standard; + // this method always returns true. + Assertions.assertTrue(metaData.supportsSchemasInProcedureCalls()); + + //From 2.0, HSQLDB supports schemas where allowed by the standard; + // this method always returns true. + Assertions.assertTrue(metaData.supportsSchemasInTableDefinitions()); + + // From 2.0, HSQLDB supports schemas where allowed by the standard; + // this method always returns true. + Assertions.assertTrue(metaData.supportsSchemasInIndexDefinitions()); + + //From 2.0, HSQLDB supports schemas where allowed by the standard; + // this method always returns true. + Assertions.assertTrue(metaData.supportsSchemasInPrivilegeDefinitions()); + + // INFORMATION_SCHEMA、PUBLIC、SYSTEM_LOBS + Assertions.assertEquals(3, getSizeOfResultSet(rs)); + + closeSQLObjects(rs); + } + + @Test + void testGetProcedures() throws SQLException { + + ResultSet rs1 = metaData.getProcedures("PUBLIC", "PUBLIC", ""); + Assertions.assertEquals(0, getSizeOfResultSet(rs1)); + + ResultSet rs2 = metaData.getProcedureColumns("PUBLIC", "PUBLIC", "", ""); + Assertions.assertEquals(0, getSizeOfResultSet(rs2)); + closeSQLObjects(rs1, rs2); + } + + @Test + void testGetTables() throws SQLException { + ResultSet rs1 = metaData.getTables("PUBLIC", "PUBLIC", "", new String[]{}); + Assertions.assertEquals(0, getSizeOfResultSet(rs1)); + + ResultSet rs2 = metaData.getTablePrivileges("PUBLIC", "PUBLIC", ""); + Assertions.assertEquals(0, getSizeOfResultSet(rs2)); + + ResultSet rs3 = metaData.getSuperTables("PUBLIC", "PUBLIC", ""); + Assertions.assertEquals(0, getSizeOfResultSet(rs3)); + closeSQLObjects(rs1, rs2, rs3); + } + + @Test + void testGetColumns() throws SQLException{ + ResultSet rs1 = metaData.getColumns("PUBLIC", "PUBLIC", "", ""); + Assertions.assertEquals(0, getSizeOfResultSet(rs1)); + + ResultSet rs2 = metaData.getColumnPrivileges("PUBLIC", "PUBLIC", "", ""); + Assertions.assertEquals(0, getSizeOfResultSet(rs2)); + closeSQLObjects(rs1, rs2); + } + + @Test + void testGetBestRowIdentifier() throws SQLException{ + ResultSet rs1 = metaData.getBestRowIdentifier("PUBLIC", "PUBLIC", "", 0, true); + Assertions.assertEquals(0, getSizeOfResultSet(rs1)); + closeSQLObjects(rs1); + } + + @Test + void testGetVersionColumns() throws SQLException{ + ResultSet rs1 = metaData.getVersionColumns("PUBLIC", "PUBLIC", ""); + Assertions.assertEquals(0, getSizeOfResultSet(rs1)); + closeSQLObjects(rs1); + } + + @Test + void testGetKeys() throws SQLException{ + ResultSet rs1 = metaData.getPrimaryKeys("PUBLIC", "PUBLIC", ""); + Assertions.assertEquals(0, getSizeOfResultSet(rs1)); + + ResultSet rs2 = metaData.getImportedKeys("PUBLIC", "PUBLIC", ""); + Assertions.assertEquals(0, getSizeOfResultSet(rs2)); + + ResultSet rs3 = metaData.getExportedKeys("PUBLIC", "PUBLIC", ""); + Assertions.assertEquals(0, getSizeOfResultSet(rs3)); + + closeSQLObjects(rs1, rs2, rs3); + } + + @Test + void testGetCrossReference() throws SQLException{ + ResultSet rs1 = metaData.getCrossReference("PUBLIC", "PUBLIC", "", "", "", ""); + Assertions.assertEquals(0, getSizeOfResultSet(rs1)); + closeSQLObjects(rs1); + } + + @Test + void testGetURL() throws SQLException { + Assertions.assertEquals("jdbc:hsqldb:mem:test;sql.syntax_mys=true", metaData.getURL()); + } + + @Test + void testGetUDTs() throws SQLException{ + ResultSet rs1 = metaData.getUDTs("PUBLIC", "PUBLIC", "", new int[]{Types.STRUCT}); + Assertions.assertEquals(0, getSizeOfResultSet(rs1)); + + ResultSet rs2 = metaData.getSuperTypes("PUBLIC", "PUBLIC", ""); + Assertions.assertEquals(0, getSizeOfResultSet(rs2)); + + + closeSQLObjects(rs1, rs2); + } + + @Test + void testGetUserName() throws SQLException { + Assertions.assertEquals("SA", metaData.getUserName()); + } + + @Test + void testIsReadOnly() throws SQLException{ + Assertions.assertFalse(metaData.isReadOnly()); + } + + @Test + void testSavePoints() throws SQLException{ + // This SQL feature is supported through JDBC as well as SQL. + Assertions.assertTrue(metaData.supportsSavepoints()); + } + + @Test + void testAttributes() throws SQLException{ + ResultSet rs1 = metaData.getAttributes("PUBLIC", "PUBLIC", "", ""); + Assertions.assertEquals(0, getSizeOfResultSet(rs1)); + closeSQLObjects(rs1); + } + + @Test + void nullsAreSorted() throws SQLException{ + // By default HSQLDB sorts null at start and this method returns false. + Assertions.assertFalse(metaData.nullsAreSortedHigh()); + // By default HSQLDB sorts null at start and this method returns false. + Assertions.assertFalse(metaData.nullsAreSortedLow()); + // By default HSQLDB sorts null at start and this method returns true. + Assertions.assertTrue(metaData.nullsAreSortedAtStart()); + // By default HSQLDB sorts null at start and this method returns false. + Assertions.assertFalse(metaData.nullsAreSortedAtEnd()); + } + + @Test + void testAllProceduresAreCallable() throws SQLException { + Assertions.assertTrue(metaData.allProceduresAreCallable()); + } + + @Test + void testAllTablesAreSelectable() throws SQLException { + Assertions.assertTrue(metaData.allTablesAreSelectable()); + } + + @Test + void testUsesLocalFiles() throws SQLException { + Assertions.assertFalse(metaData.usesLocalFiles()); + Assertions.assertFalse(metaData.usesLocalFilePerTable()); + } + + @Test + void testIdentifiers() throws SQLException { + //HSQLDB treats unquoted identifiers as case insensitive and stores them in upper case. + // It treats quoted identifiers as case sensitive and stores them verbatim; + // this method always returns false. + Assertions.assertFalse(metaData.supportsMixedCaseIdentifiers()); + + Assertions.assertTrue(metaData.supportsMixedCaseQuotedIdentifiers()); + + // this method always returns true. + Assertions.assertTrue(metaData.storesUpperCaseIdentifiers()); + + // this method always returns false. + Assertions.assertFalse(metaData.storesLowerCaseIdentifiers()); + + // this method always returns false. + Assertions.assertFalse(metaData.storesMixedCaseIdentifiers()); + + // this method always returns false. + Assertions.assertFalse(metaData.storesLowerCaseQuotedIdentifiers()); + + // this method always returns false. + Assertions.assertFalse(metaData.storesUpperCaseQuotedIdentifiers()); + + // this method always returns false. + Assertions.assertFalse(metaData.storesMixedCaseQuotedIdentifiers()); + + // HSQLDB uses the standard SQL identifier quote character (the double quote character); + // this method always returns " + Assertions.assertEquals("\"", metaData.getIdentifierQuoteString()); + + // The list is empty. + // However, HSQLDB also supports SQL:2008 keywords + // and disallows them for database object names without double quoting. + Assertions.assertEquals("", metaData.getSQLKeywords()); + + // HSQLDB supports transactions; this method always returns true. + Assertions.assertTrue(metaData.supportsTransactions()); + + // HSQLDB supports all levels. + Assertions.assertTrue(metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_SERIALIZABLE)); + + // HSQLDB does not support a mix of both data definition and data manipulation statements within a transaction. + // DDL commits the current transaction before proceeding; this method always returns false. + Assertions.assertFalse(metaData.supportsDataDefinitionAndDataManipulationTransactions()); + + // HSQLDB supports only data manipulation statements within a transaction. + // DDL commits the current transaction before proceeding, while DML does not; this method always returns true. + Assertions.assertTrue(metaData.supportsDataManipulationTransactionsOnly()); + + // Including 2.0, a data definition statement within a transaction forces the transaction to commit; + // this method always returns true. + Assertions.assertTrue(metaData.dataDefinitionCausesTransactionCommit()); + + // Including 2.0, a data definition statement is not ignored within a transaction. + // Rather, a data definition statement within a transaction forces the transaction to commit; this method always returns false. + Assertions.assertFalse(metaData.dataDefinitionIgnoredInTransactions()); + + + } + + @Test + void testGetFunction() throws SQLException{ + Assertions.assertEquals( + "ABS,ACOS,ASIN,ATAN,ATAN2,BITAND,BITOR,BITXOR," + + "CEILING,COS,COT,DEGREES,EXP,FLOOR,LOG,LOG10," + + "MOD,PI,POWER,RADIANS,RAND,ROUND,ROUNDMAGIC," + + "SIGN,SIN,SQRT,TAN,TRUNCATE", + metaData.getNumericFunctions()); + + Assertions.assertEquals( + "ASCII,CHAR,CONCAT,DIFFERENCE,HEXTORAW,INSERT,LCASE," + + "LEFT,LENGTH,LOCATE,LTRIM,RAWTOHEX,REPEAT,REPLACE,RIGHT," + + "RTRIM,SOUNDEX,SPACE,SUBSTR,UCASE", + metaData.getStringFunctions()); + + Assertions.assertEquals( + "DATABASE,IFNULL,USER", + metaData.getSystemFunctions()); + + Assertions.assertEquals( + "CURDATE,CURTIME,DATEDIFF,DAYNAME,DAYOFMONTH,DAYOFWEEK,DAYOFYEAR," + + "HOUR,MINUTE,MONTH,MONTHNAME,NOW,QUARTER,SECOND,SECONDS_SINCE_MIDNIGHT," + + "TIMESTAMPADD,TIMESTAMPDIFF,TO_CHAR,WEEK,YEAR", + metaData.getTimeDateFunctions()); + } + + @Test + void testGetSpecialStringAndCharacters() throws SQLException { + //Retrieves the string that can be used to escape wildcard characters. + // This is the string that can be used to escape '_' or '%' + // in the catalog search parameters that are a pattern (and therefore use one of the wildcard characters). + Assertions.assertEquals("\\", metaData.getSearchStringEscape()); + + // By default HSQLDB does not support using any "extra" characters in unquoted identifier names; + // this method always returns the empty String. + Assertions.assertEquals("", metaData.getExtraNameCharacters()); + } + + @Test + void tesOperationSupport() throws SQLException{ + // HSQLDB supports this type of ALTER TABLE statement; this method always returns true. + Assertions.assertTrue(metaData.supportsAlterTableWithAddColumn()); + + // HSQLDB supports this type of ALTER TABLE statement; this method always returns true. + Assertions.assertTrue(metaData.supportsAlterTableWithDropColumn()); + + // HSQLDB supports column aliasing; this method always returns true. + Assertions.assertTrue(metaData.supportsColumnAliasing()); + + // By default HSQLDB returns NULL when NULL and non-NULL values are concatenated. + // this method returns true, concat_nulls property has a non-default value. + Assertions.assertTrue(metaData.nullPlusNonNullIsNull()); + + // HSQLDB supports conversions; this method always returns true. + Assertions.assertTrue(metaData.supportsConvert()); + + // HSQLDB 2.0 supports conversion according to SQL standards. + // In addition, it supports conversion between values of BOOLEAN and BIT types. + Assertions.assertTrue(metaData.supportsConvert(Types.INTEGER, Types.DOUBLE)); + + // HSQLDB supports table correlation names; this method always returns true. + Assertions.assertTrue(metaData.supportsTableCorrelationNames()); + + // HSQLDB does not require that table correlation names are different from the names of the tables; + // this method always returns false. + Assertions.assertFalse(metaData.supportsDifferentTableCorrelationNames()); + + // HSQLDB supports expressions in ORDER BY lists; this method always returns true. + Assertions.assertTrue(metaData.supportsExpressionsInOrderBy()); + + // HSQLDB supports using a column that is not in the SELECT statement in an ORDER BY clause; + // this method always returns true. + Assertions.assertTrue(metaData.supportsOrderByUnrelated()); + + // HSQLDB supports using the GROUP BY clause; this method always returns true. + Assertions.assertTrue(metaData.supportsGroupBy()); + + // HSQLDB supports using a column that is not in the SELECT statement in a GROUP BY clause; + // this method always returns true. + Assertions.assertTrue(metaData.supportsGroupByUnrelated()); + + // HSQLDB supports using columns not included in the SELECT statement in a GROUP BY clause provided that + // all of the columns in the SELECT statement are included in the GROUP BY clause; + // this method always returns true. + Assertions.assertTrue(metaData.supportsGroupByBeyondSelect()); + + // HSQLDB supports specifying a LIKE escape clause; + // this method always returns true. + Assertions.assertTrue(metaData.supportsLikeEscapeClause()); + + // HSQLDB 2.0 supports getting multiple ResultSet objects + // from a single call to the method execute of the CallableStatement interface; + // this method returns true. + Assertions.assertTrue(metaData.supportsMultipleResultSets()); + + // Retrieves whether this database allows having multiple transactions open at once (on different connections). + Assertions.assertTrue(metaData.supportsMultipleTransactions()); + + // Retrieves whether columns in this database may be defined as non-nullable. + Assertions.assertTrue(metaData.supportsNonNullableColumns()); + + // From 2.0, HSQLDB supports the ODBC Minimum SQL grammar; this method always returns true. + Assertions.assertTrue(metaData.supportsMinimumSQLGrammar()); + + // From 2.0, HSQLDB supports the ODBC Core SQL grammar; this method always returns true. + Assertions.assertTrue(metaData.supportsCoreSQLGrammar()); + + // From 2.0, HSQLDB supports the ODBC Extended SQL grammar; this method always returns true. + Assertions.assertTrue(metaData.supportsExtendedSQLGrammar()); + + // From 2.0, HSQLDB supports the ANSI92 entry level SQL grammar; this method always returns true. + Assertions.assertTrue(metaData.supportsANSI92EntryLevelSQL()); + + // From 2.0, HSQLDB supports the ANSI92 intermediate SQL grammar; this method always returns true. + Assertions.assertTrue(metaData.supportsANSI92IntermediateSQL()); + + // From 2.0, HSQLDB supports the ANSI92 full SQL grammar. The exceptions, such as support for ASSERTION, are not considered grammar issues. + // This method always returns true. + Assertions.assertTrue(metaData.supportsANSI92FullSQL()); + + // This method always returns true. + Assertions.assertTrue(metaData.supportsIntegrityEnhancementFacility()); + + // HSQLDB supports outer joins; this method always returns true. + Assertions.assertTrue(metaData.supportsOuterJoins()); + + // From 2.0, HSQLDB supports full nested outer joins; + // this method always returns true. + Assertions.assertTrue(metaData.supportsFullOuterJoins()); + + // HSQLDB supports the LEFT OUTER join syntax; this method always returns true. + Assertions.assertTrue(metaData.supportsLimitedOuterJoins()); + + // HSQLDB 2.0 supports updatable result sets; this method always returns true. + Assertions.assertTrue(metaData.supportsPositionedDelete()); + + // HSQLDB 2.0 supports updatable result sets; this method always returns true. + Assertions.assertTrue(metaData.supportsPositionedUpdate()); + + // HSQLDB 2.0 supports updatable result sets; this method always returns true. + Assertions.assertTrue(metaData.supportsSelectForUpdate()); + + // HSQLDB supports calling public static Java methods in the context of SQL Stored Procedures; + // this method always returns true. + Assertions.assertTrue(metaData.supportsStoredProcedures()); + + // HSQLDB has always supported subqueries in comparison expressions; + // this method always returns true. + Assertions.assertTrue(metaData.supportsSubqueriesInComparisons()); + + // HSQLDB has always supported subqueries in EXISTS expressions; + // this method always returns true. + Assertions.assertTrue(metaData.supportsSubqueriesInExists()); + + // HSQLDB has always supported subqueries in IN statements; + // this method always returns true. + Assertions.assertTrue(metaData.supportsSubqueriesInIns()); + + // HSQLDB has always supported subqueries in quantified expressions; + // this method always returns true. + Assertions.assertTrue(metaData.supportsSubqueriesInQuantifieds()); + + // HSQLDB has always supported correlated subqueries; + // this method always returns true. + Assertions.assertTrue(metaData.supportsCorrelatedSubqueries()); + + // HSQLDB supports SQL UNION; + // this method always returns true. + Assertions.assertTrue(metaData.supportsUnion()); + + // HSQLDB supports SQL UNION ALL; + // this method always returns true. + Assertions.assertTrue(metaData.supportsUnionAll()); + + // HSQLDB 2.0 supports keeping cursors open across commits. + // This method always returns true. + Assertions.assertTrue(metaData.supportsOpenCursorsAcrossCommit()); + + // HSQLDB 2.0 closes open cursors at rollback. + // This method always returns false. + Assertions.assertFalse(metaData.supportsOpenCursorsAcrossRollback()); + + // HSQLDB supports keeping statements open across commits; + // this method always returns true. + Assertions.assertTrue(metaData.supportsOpenStatementsAcrossCommit()); + + // HSQLDB supports keeping statements open across rollbacks; this method always returns true. + // This method always returns true. + Assertions.assertTrue(metaData.supportsOpenStatementsAcrossRollback()); + + /** + * Including 2.0, getMaxRowSize() always returns 0, indicating that the maximum row size is unknown or has no limit. + * This applies to the above types as well; this method always returns true. + */ + Assertions.assertTrue(metaData.doesMaxRowSizeIncludeBlobs()); + + Assertions.assertTrue(metaData.supportsResultSetType(ResultSet.TYPE_FORWARD_ONLY)); + + /** + * CONCUR_READ_ONLY: If you set this as a value of the concurrency while creating the ResultSet object + * you cannot update the contents of the ResultSet you can only read/retrieve them. + * + * CONCUR_UPDATABLE: If you set this as a value of the concurrency while creating the ResultSet object + * you can update the contents of the ResultSet. + */ + Assertions.assertTrue(metaData.supportsResultSetConcurrency( + ResultSet.TYPE_FORWARD_ONLY, + ResultSet.CONCUR_READ_ONLY)); + + // Updates to ResultSet rows are not visible after moving from the updated row. + Assertions.assertFalse(metaData.ownUpdatesAreVisible(ResultSet.TYPE_FORWARD_ONLY)); + + // Rows deleted from the ResultSet are still visible after moving from the deleted row. + Assertions.assertFalse(metaData.ownDeletesAreVisible(ResultSet.TYPE_FORWARD_ONLY)); + + //Rows added to a ResultSet are not visible after moving from the insert row; + // this method always returns false. + Assertions.assertFalse(metaData.ownInsertsAreVisible(ResultSet.TYPE_FORWARD_ONLY)); + + // Updates made by other connections or the same connection + // while the ResultSet is open are not visible in the ResultSet. + Assertions.assertFalse(metaData.othersUpdatesAreVisible(ResultSet.TYPE_FORWARD_ONLY)); + + // Deletes made by other connections or the same connection + // while the ResultSet is open are not visible in the ResultSet. + Assertions.assertFalse(metaData.othersDeletesAreVisible(ResultSet.TYPE_FORWARD_ONLY)); + + // Inserts made by other connections or the same connection + // while the ResultSet is open are not visible in the ResultSet. + Assertions.assertFalse(metaData.othersInsertsAreVisible(ResultSet.TYPE_FORWARD_ONLY)); + + // Updates made to the rows of the ResultSet are not detected by calling the ResultSet.rowUpdated. + Assertions.assertFalse(metaData.updatesAreDetected(ResultSet.TYPE_FORWARD_ONLY)); + + // Deletes made to the rows of the ResultSet are not detected by calling the ResultSet.rowDeleted. + Assertions.assertFalse(metaData.deletesAreDetected(ResultSet.TYPE_FORWARD_ONLY)); + + // Inserts made into the ResultSet are not visible and thus not detected by calling the ResultSet.rowInserted. + Assertions.assertFalse(metaData.insertsAreDetected(ResultSet.TYPE_FORWARD_ONLY)); + + // HSQLDB supports batch updates; this method always returns true. + Assertions.assertTrue(metaData.supportsBatchUpdates()); + + // HSQLDB supports JDBC named parameters to callable statements; this method returns true. + Assertions.assertTrue(metaData.supportsNamedParameters()); + + // HSQLDB supports multiple ResultSet objects returned from a CallableStatement; + // this method always returns true. + Assertions.assertTrue(metaData.supportsMultipleOpenResults()); + + // HSQLDB supports retrieval of autogenerated keys through the JDBC interface; + // this method always returns true. + Assertions.assertTrue(metaData.supportsGetGeneratedKeys()); + + Assertions.assertFalse(metaData.locatorsUpdateCopy()); + + // Starting with 2.0, HSQLDB supports statement pooling when built under JDK 1.6+. + Assertions.assertTrue(metaData.supportsStatementPooling()); + + Assertions.assertTrue(metaData.supportsStoredFunctionsUsingCallSyntax()); + + Assertions.assertFalse(metaData.autoCommitFailureClosesAllResultSets()); + } + + @Test + void testHoldability() throws SQLException{ + // HSQLDB returns true for both alternatives. + Assertions.assertTrue(metaData.supportsResultSetHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT)); + + // HSQLDB defaults to HOLD_CURSORS_OVER_COMMIT for CONSUR_READ_ONLY ResultSet objects. + // If the ResultSet concurrency is CONCUR_UPDATABLE, + // then holdability is is enforced as CLOSE_CURSORS_AT_COMMIT. + Assertions.assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, metaData.getResultSetHoldability()); + } + + @Test + void testTerm() throws SQLException { + + // Starting with 1.8.0, HSQLDB supports schemas. + Assertions.assertEquals("SCHEMA", metaData.getSchemaTerm()); + + // From 2.0, HSQLDB supports declaration of functions or procedures directly in SQL. + Assertions.assertEquals("PROCEDURE", metaData.getProcedureTerm()); + + // HSQLDB uses the standard name CATALOG. + Assertions.assertEquals("CATALOG", metaData.getCatalogTerm()); + } + + @Test + void testGetDefaultInformation() throws SQLException { + // HSQLDB does not impose a "known" limit. The limit is subject to memory availability; + // this method always returns 0. + Assertions.assertEquals(0, metaData.getMaxBinaryLiteralLength()); + + // HSQLDB does not impose a "known" limit. The limit is subject to memory availability; + // this method always returns 0. + Assertions.assertEquals(0, metaData.getMaxCharLiteralLength()); + + // Starting with 2.0, HSQLDB implements the SQL standard, + // which is 128 for all names. + Assertions.assertEquals(128, metaData.getMaxColumnNameLength()); + + // HSQLDB does not impose a "known" limit. The limit is subject to memory availability; + // this method always returns 0. + Assertions.assertEquals(0, metaData.getMaxColumnsInGroupBy()); + + // HSQLDB does not impose a "known" limit. The limit is subject to memory availability; + // this method always returns 0. + Assertions.assertEquals(0, metaData.getMaxColumnsInIndex()); + + // HSQLDB does not impose a "known" limit. The limit is subject to memory availability; + // this method always returns 0. + Assertions.assertEquals(0, metaData.getMaxColumnsInOrderBy()); + + // HSQLDB does not impose a "known" limit. The limit is subject to memory availability; + // this method always returns 0. + Assertions.assertEquals(0, metaData.getMaxColumnsInSelect()); + + // HSQLDB does not impose a "known" limit. The limit is subject to memory availability; + // this method always returns 0. + Assertions.assertEquals(0, metaData.getMaxColumnsInTable()); + + // HSQLDB does not impose a "known" limit. The limit is subject to memory availability; + // this method always returns 0. + Assertions.assertEquals(0, metaData.getMaxConnections()); + + // Starting with 2.0, HSQLDB implements the SQL standard, which is 128 for all names. + Assertions.assertEquals(128, metaData.getMaxCursorNameLength()); + + // HSQLDB does not impose a "known" limit. The limit is subject to memory and disk availability; + // this method always returns 0. + Assertions.assertEquals(0, metaData.getMaxIndexLength()); + + // Starting with 2.0, HSQLDB implements the SQL standard, + // which is 128 for all names. + Assertions.assertEquals(128, metaData.getMaxSchemaNameLength()); + + // Starting with 2.0, HSQLDB implements the SQL standard, + // which is 128 for all names. + Assertions.assertEquals(128, metaData.getMaxProcedureNameLength()); + + // Starting with 2.0, HSQLDB implements the SQL standard, + // which is 128 for all names. + Assertions.assertEquals(128, metaData.getMaxCatalogNameLength()); + + // Starting with 2.0, HSQLDB implements the SQL standard, + // which is 128 for all names. + Assertions.assertEquals(128, metaData.getMaxCatalogNameLength()); + + // HSQLDB does not impose a "known" limit. The limit is subject to memory availability; + // this method always returns 0. + Assertions.assertEquals(0, metaData.getMaxStatementLength()); + + // HSQLDB does not impose a "known" limit. The limit is subject to memory availability; + // this method always returns 0. + Assertions.assertEquals(0, metaData.getMaxStatements()); + + // Up to and including 1.8.0.x, HSQLDB did not impose a "known" limit. + // Th hard limit was the maximum length of a java.lang.String (java.lang.Integer.MAX_VALUE); + // this method always returned 0. + // Starting with 2.0, HSQLDB implements the SQL standard, which is 128 for all names. + Assertions.assertEquals(128, metaData.getMaxTableNameLength()); + + // HSQLDB does not impose a "known" limit. + // The limit is subject to memory availability; this method always returns 0. + Assertions.assertEquals(0, metaData.getMaxTablesInSelect()); + + // Starting with 2.0, HSQLDB implements the SQL standard, which is 128 for all names. + Assertions.assertEquals(128, metaData.getMaxUserNameLength()); + + // Default isolation mode in version 2.0 is TRANSACTION_READ_COMMITTED. + Assertions.assertEquals(Connection.TRANSACTION_READ_COMMITTED, metaData.getDefaultTransactionIsolation()); + } + + @Test + void getInfo() throws SQLException{ + ResultSet rs1 = metaData.getTypeInfo(); + Assertions.assertEquals(23, getSizeOfResultSet(rs1)); + + ResultSet rs2 = metaData.getIndexInfo("PUBLIC", "PUBLIC", "", true, true); + Assertions.assertEquals(0, getSizeOfResultSet(rs2)); + + closeSQLObjects(rs1, rs2); + } }