diff --git a/src/main/java/org/tarantool/jdbc/SQLConnection.java b/src/main/java/org/tarantool/jdbc/SQLConnection.java index 3f299151..15333871 100644 --- a/src/main/java/org/tarantool/jdbc/SQLConnection.java +++ b/src/main/java/org/tarantool/jdbc/SQLConnection.java @@ -479,13 +479,13 @@ private void throwUnknownClientProperties(Collection properties) throws @Override public String getClientInfo(String name) throws SQLException { checkNotClosed(); - throw new SQLFeatureNotSupportedException(); + return null; } @Override public Properties getClientInfo() throws SQLException { checkNotClosed(); - throw new SQLFeatureNotSupportedException(); + return new Properties(); } @Override diff --git a/src/main/java/org/tarantool/jdbc/SQLDatabaseMetadata.java b/src/main/java/org/tarantool/jdbc/SQLDatabaseMetadata.java index b3b0d024..61b66873 100644 --- a/src/main/java/org/tarantool/jdbc/SQLDatabaseMetadata.java +++ b/src/main/java/org/tarantool/jdbc/SQLDatabaseMetadata.java @@ -1,5 +1,7 @@ package org.tarantool.jdbc; +import static org.tarantool.util.JdbcConstants.DatabaseMetadataTable; + import org.tarantool.SqlProtoUtils; import org.tarantool.Version; @@ -13,7 +15,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -29,14 +30,14 @@ public class SQLDatabaseMetadata implements DatabaseMetaData { public static final int SPACE_ID_IDX = 0; protected final SQLConnection connection; + public SQLDatabaseMetadata(SQLConnection connection) { + this.connection = connection; + } + @Override public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException { - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); - } - - public SQLDatabaseMetadata(SQLConnection connection) { - this.connection = connection; + return asEmptyMetadataResultSet(DatabaseMetadataTable.STORED_PROCEDURES); } @Override @@ -635,7 +636,7 @@ public ResultSet getProcedureColumns(String catalog, String procedureNamePattern, String columnNamePattern) throws SQLException { - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); + return asEmptyMetadataResultSet(DatabaseMetadataTable.STORED_PROCEDURE_COLUMNS); } @Override @@ -644,7 +645,7 @@ public ResultSet getTables(String catalog, String schemaPattern, String tableNam try { if (types != null && !Arrays.asList(types).contains("TABLE")) { connection.checkNotClosed(); - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); + return asEmptyMetadataResultSet(DatabaseMetadataTable.TABLES); } String[] parts = tableNamePattern == null ? new String[] { "" } : tableNamePattern.split("%"); List> spaces = (List>) connection.nativeSelect( @@ -659,19 +660,17 @@ public ResultSet getTables(String catalog, String schemaPattern, String tableNam * Skip spaces that don't have format. Tarantool/SQL does not support such spaces. */ if (!tableName.startsWith("_") && format.size() > 0 && like(tableName, parts)) { - rows.add(Arrays.asList((Object) tableName, (Object) "TABLE")); + rows.add(Arrays.asList( + null, null, + tableName, + "TABLE", + null, null, + null, null, + null, null) + ); } } - List columnNames = Arrays.asList( - "TABLE_NAME", "TABLE_TYPE", - //nulls - "REMARKS", "TABLE_CAT", - "TABLE_SCHEM", "TABLE_TYPE", - "TYPE_CAT", "TYPE_SCHEM", - "TYPE_NAME", "SELF_REFERENCING_COL_NAME", - "REF_GENERATION" - ); - return sqlNullResultSet(columnNames, rows); + return asMetadataResultSet(DatabaseMetadataTable.TABLES, rows); } catch (Exception e) { throw new SQLException( "Failed to retrieve table(s) description: " + @@ -697,32 +696,30 @@ protected boolean like(String value, String[] parts) { @Override public ResultSet getTableTypes() throws SQLException { return asMetadataResultSet( - SQLResultHolder.ofQuery( - Arrays.asList(new SqlProtoUtils.SQLMetaData("TABLE_TYPE")), - Arrays.asList(Arrays.asList("TABLE")) - ) + DatabaseMetadataTable.TABLE_TYPES, + Collections.singletonList(Arrays.asList("TABLE")) ); } @Override public ResultSet getSchemas() throws SQLException { - return rowOfNullsResultSet(); + return asEmptyMetadataResultSet(DatabaseMetadataTable.SCHEMAS); } @Override public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException { - return rowOfNullsResultSet(); + return asEmptyMetadataResultSet(DatabaseMetadataTable.SCHEMAS); } @Override public ResultSet getCatalogs() throws SQLException { - return rowOfNullsResultSet(); + return asEmptyMetadataResultSet(DatabaseMetadataTable.CATALOGS); } @Override public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException { - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); + return asEmptyMetadataResultSet(DatabaseMetadataTable.BEST_ROW_IDENTIFIER); } @Override @@ -746,39 +743,40 @@ public ResultSet getColumns(String catalog, String schemaPattern, String tableNa for (int columnIdx = 1; columnIdx <= format.size(); columnIdx++) { Map f = format.get(columnIdx - 1); String columnName = (String) f.get("name"); - String dbType = (String) f.get("type"); + String typeName = (String) f.get("type"); if (like(columnName, colParts)) { rows.add(Arrays.asList( - tableName, columnName, - columnIdx, Types.OTHER, - dbType, 10, 1, - "YES", Types.OTHER, - "NO", "NO") + null, // table catalog + null, // table schema + tableName, + columnName, + Types.OTHER, // data type + typeName, + null, // column size + null, // buffer length + null, // decimal digits + 10, // num prec radix + columnNullableUnknown, + null, // remarks + null, // column def + null, // sql data type + null, // sql datatype sub + null, // char octet length + columnIdx, // ordinal position + "", // is nullable + null, // scope catalog + null, // scope schema + null, // scope table + Types.OTHER, // source data type + "NO", // is autoincrement + "NO") // is generated column ); } } } } - List columnNames = Arrays.asList( - "TABLE_NAME", "COLUMN_NAME", - "ORDINAL_POSITION", "DATA_TYPE", - "TYPE_NAME", "NUM_PREC_RADIX", - "NULLABLE", "IS_NULLABLE", - "SOURCE_DATA_TYPE", "IS_AUTOINCREMENT", - "IS_GENERATEDCOLUMN", - //nulls - "TABLE_CAT", "TABLE_SCHEM", - "COLUMN_SIZE", "BUFFER_LENGTH", - "DECIMAL_DIGITS", "REMARKS", - "COLUMN_DEF", "SQL_DATA_TYPE", - "SQL_DATETIME_SUB", "CHAR_OCTET_LENGTH", - "SCOPE_CATALOG", "SCOPE_SCHEMA", - "SCOPE_TABLE" - ); - return sqlNullResultSet( - columnNames, - rows); + return asMetadataResultSet(DatabaseMetadataTable.COLUMNS, rows); } catch (Exception e) { throw new SQLException( "Error processing table column metadata: " + @@ -790,41 +788,37 @@ public ResultSet getColumns(String catalog, String schemaPattern, String tableNa @Override public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException { - return rowOfNullsResultSet(); + return asEmptyMetadataResultSet(DatabaseMetadataTable.COLUMN_PRIVILEGES); } @Override public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { - return rowOfNullsResultSet(); + return asEmptyMetadataResultSet(DatabaseMetadataTable.TABLE_PRIVILEGES); } @Override public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException { - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); + return asEmptyMetadataResultSet(DatabaseMetadataTable.VERSION_COLUMNS); } @Override public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException { - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); + return asEmptyMetadataResultSet(DatabaseMetadataTable.FOREIGN_KEYS); } @Override public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException { - final List colNames = Arrays.asList( - "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "KEY_SEQ", "PK_NAME" - ); - if (table == null || table.isEmpty()) { connection.checkNotClosed(); - return emptyResultSet(colNames); + return asEmptyMetadataResultSet(DatabaseMetadataTable.PRIMARY_KEYS); } try { List spaces = connection.nativeSelect(_VSPACE, 2, Collections.singletonList(table), 0, 1, 0); if (spaces == null || spaces.size() == 0) { - return emptyResultSet(colNames); + return asEmptyMetadataResultSet(DatabaseMetadataTable.PRIMARY_KEYS); } List space = ensureType(List.class, spaces.get(0)); @@ -840,7 +834,7 @@ public ResultSet getPrimaryKeys(String catalog, String schema, String table) thr // We only accept SQL spaces, for which the parts is 'List of Maps'. Map part = checkType(Map.class, parts.get(i)); if (part == null) { - return emptyResultSet(colNames); + return asEmptyMetadataResultSet(DatabaseMetadataTable.PRIMARY_KEYS); } int ordinal = ensureType(Number.class, part.get("field")).intValue(); @@ -850,15 +844,12 @@ public ResultSet getPrimaryKeys(String catalog, String schema, String table) thr rows.add(Arrays.asList(null, null, table, column, i + 1, primaryKey.get(NAME_IDX))); } // Sort results by column name. - Collections.sort(rows, new Comparator>() { - @Override - public int compare(List row0, List row1) { - String col0 = (String) row0.get(3); - String col1 = (String) row1.get(3); - return col0.compareTo(col1); - } + rows.sort((left, right) -> { + String col0 = (String) left.get(3); + String col1 = (String) right.get(3); + return col0.compareTo(col1); }); - return sqlNullResultSet(colNames, rows); + return asMetadataResultSet(DatabaseMetadataTable.PRIMARY_KEYS, rows); } catch (Exception e) { throw new SQLException("Error processing metadata for table \"" + table + "\".", e); } @@ -866,7 +857,7 @@ public int compare(List row0, List row1) { @Override public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException { - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); + return asEmptyMetadataResultSet(DatabaseMetadataTable.FOREIGN_KEYS); } @Override @@ -877,24 +868,24 @@ public ResultSet getCrossReference(String parentCatalog, String foreignSchema, String foreignTable) throws SQLException { - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); + return asEmptyMetadataResultSet(DatabaseMetadataTable.FOREIGN_KEYS); } @Override public ResultSet getTypeInfo() throws SQLException { - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); + return asEmptyMetadataResultSet(DatabaseMetadataTable.TYPE_INFO); } @Override public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException { - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); + return asEmptyMetadataResultSet(DatabaseMetadataTable.INDEX_INFO); } @Override public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException { - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); + return asEmptyMetadataResultSet(DatabaseMetadataTable.UDTS); } @Override @@ -960,7 +951,7 @@ public boolean supportsBatchUpdates() throws SQLException { @Override public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) throws SQLException { - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); + return asEmptyMetadataResultSet(DatabaseMetadataTable.SUPER_TYPES); } @Override @@ -990,21 +981,20 @@ public boolean supportsGetGeneratedKeys() throws SQLException { @Override public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); + return asEmptyMetadataResultSet(DatabaseMetadataTable.SUPER_TABLES); } @Override public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, - String attributeNamePattern) - throws SQLException { - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); + String attributeNamePattern) throws SQLException { + return asEmptyMetadataResultSet(DatabaseMetadataTable.ATTRIBUTES); } @Override public ResultSet getClientInfoProperties() throws SQLException { - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); + return asEmptyMetadataResultSet(DatabaseMetadataTable.CLIENT_INFO_PROPERTIES); } /** @@ -1076,7 +1066,7 @@ public boolean autoCommitFailureClosesAllResultSets() throws SQLException { @Override public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) throws SQLException { - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); + return asEmptyMetadataResultSet(DatabaseMetadataTable.FUNCTIONS); } @Override @@ -1085,7 +1075,7 @@ public ResultSet getFunctionColumns(String catalog, String functionNamePattern, String columnNamePattern) throws SQLException { - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); + return asEmptyMetadataResultSet(DatabaseMetadataTable.FUNCTION_COLUMNS); } @Override @@ -1094,13 +1084,21 @@ public ResultSet getPseudoColumns(String catalog, String tableNamePattern, String columnNamePattern) throws SQLException { - return asMetadataResultSet(SQLResultHolder.ofEmptyQuery()); + return asEmptyMetadataResultSet(DatabaseMetadataTable.PSEUDO_COLUMNS); } - private ResultSet asMetadataResultSet(SQLResultHolder holder) throws SQLException { + private ResultSet asMetadataResultSet(List columnNames, List> rows) throws SQLException { + List meta = columnNames.stream() + .map(SqlProtoUtils.SQLMetaData::new) + .collect(Collectors.toList()); + SQLResultHolder holder = SQLResultHolder.ofQuery(meta, rows); return createMetadataStatement().executeMetadata(holder); } + private ResultSet asEmptyMetadataResultSet(List columnNames) throws SQLException { + return asMetadataResultSet(columnNames, Collections.emptyList()); + } + @Override public boolean generatedKeyAlwaysReturned() throws SQLException { return false; @@ -1119,13 +1117,6 @@ public boolean isWrapperFor(Class type) throws SQLException { return type.isAssignableFrom(this.getClass()); } - private SQLNullResultSet sqlNullResultSet(List columnNames, List> rows) throws SQLException { - List meta = columnNames.stream() - .map(SqlProtoUtils.SQLMetaData::new) - .collect(Collectors.toList()); - return new SQLNullResultSet(SQLResultHolder.ofQuery(meta, rows), createMetadataStatement()); - } - private TarantoolStatement createMetadataStatement() throws SQLException { return connection.createStatement().unwrap(TarantoolStatement.class); } @@ -1142,32 +1133,4 @@ private static T checkType(Class cls, Object v) { return (v != null && cls.isAssignableFrom(v.getClass())) ? cls.cast(v) : null; } - private SQLNullResultSet rowOfNullsResultSet() throws SQLException { - return sqlNullResultSet(Collections.emptyList(), Collections.emptyList()); - } - - private SQLNullResultSet emptyResultSet(List colNames) throws SQLException { - return sqlNullResultSet(colNames, Collections.emptyList()); - } - - protected class SQLNullResultSet extends SQLResultSet { - - public SQLNullResultSet(SQLResultHolder holder, TarantoolStatement ownerStatement) throws SQLException { - super(holder, ownerStatement); - } - - @Override - protected Object getRaw(int columnIndex) throws SQLException { - List row = getCurrentRow(); - return columnIndex > row.size() ? null : row.get(columnIndex - 1); - } - - @Override - protected int findColumnIndex(String columnLabel) throws SQLException { - int index = super.findColumnIndex(columnLabel); - return index == 0 ? Integer.MAX_VALUE : index; - } - - } - } diff --git a/src/main/java/org/tarantool/util/JdbcConstants.java b/src/main/java/org/tarantool/util/JdbcConstants.java index dfbad572..32ce2007 100644 --- a/src/main/java/org/tarantool/util/JdbcConstants.java +++ b/src/main/java/org/tarantool/util/JdbcConstants.java @@ -4,9 +4,15 @@ import java.sql.SQLException; import java.sql.SQLNonTransientException; import java.sql.Statement; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; public class JdbcConstants { + private JdbcConstants() { + } + public static void checkGeneratedKeysConstant(int autoGeneratedKeys) throws SQLException { if (autoGeneratedKeys != Statement.NO_GENERATED_KEYS && autoGeneratedKeys != Statement.RETURN_GENERATED_KEYS) { @@ -21,4 +27,311 @@ public static void checkHoldabilityConstant(int holdability) throws SQLException } } + public static class DatabaseMetadataTable { + + private DatabaseMetadataTable() { + } + + public static List STORED_PROCEDURES = Arrays.asList( + "PROCEDURE_CAT", + "PROCEDURE_SCHEM", + "PROCEDURE_NAME", + "RESERVED_1", + "RESERVED_2", + "RESERVED_3", + "REMARKS", + "PROCEDURE_TYPE", + "SPECIFIC_NAME" + ); + + public static List STORED_PROCEDURE_COLUMNS = Arrays.asList( + "PROCEDURE_CAT", + "PROCEDURE_SCHEM", + "PROCEDURE_NAME", + "COLUMN_NAME", + "COLUMN_TYPE", + "DATA_TYPE", + "TYPE_NAME", + "PRECISION", + "LENGTH", + "SCALE", + "RADIX", + "NULLABLE", + "REMARKS", + "COLUMN_DEF", + "SQL_DATA_TYPE", + "SQL_DATETIME_SUB", + "CHAR_OCTET_LENGTH", + "ORDINAL_POSITION", + "IS_NULLABLE", + "SPECIFIC_NAME" + ); + + public static List TABLES = Arrays.asList( + "TABLE_CAT", + "TABLE_SCHEM", + "TABLE_NAME", + "TABLE_TYPE", + "REMARKS", + "TYPE_CAT", + "TYPE_SCHEM", + "TYPE_NAME", + "SELF_REFERENCING_COL_NAME", + "REF_GENERATION" + ); + + public static List TABLE_TYPES = Collections.singletonList( + "TABLE_TYPE" + ); + + public static List SCHEMAS = Arrays.asList( + "TABLE_SCHEM", + "TABLE_CATALOG" + ); + + public static List CATALOGS = Collections.singletonList( + "TABLE_CAT" + ); + + public static List BEST_ROW_IDENTIFIER = Arrays.asList( + "SCOPE", + "COLUMN_NAME", + "DATA_TYPE", + "TYPE_NAME", + "COLUMN_SIZE", + "BUFFER_LENGTH", + "DECIMAL_DIGITS", + "PSEUDO_COLUMN" + ); + + public static List COLUMNS = Arrays.asList( + "TABLE_CAT", + "TABLE_SCHEM", + "TABLE_NAME", + "COLUMN_NAME", + "DATA_TYPE", + "TYPE_NAME", + "COLUMN_SIZE", + "BUFFER_LENGTH", + "DECIMAL_DIGITS", + "NUM_PREC_RADIX", + "NULLABLE", + "REMARKS", + "COLUMN_DEF", + "SQL_DATA_TYPE", + "SQL_DATETIME_SUB", + "CHAR_OCTET_LENGTH", + "ORDINAL_POSITION", + "IS_NULLABLE", + "SCOPE_CATALOG", + "SCOPE_SCHEMA", + "SCOPE_TABLE", + "SOURCE_DATA_TYPE", + "IS_AUTOINCREMENT", + "IS_GENERATEDCOLUMN" + ); + + public static List COLUMN_PRIVILEGES = Arrays.asList( + "TABLE_CAT", + "TABLE_SCHEM", + "TABLE_NAME", + "COLUMN_NAME", + "GRANTOR", + "GRANTEE", + "PRIVILEGE", + "IS_GRANTABLE" + ); + + public static List TABLE_PRIVILEGES = Arrays.asList( + "TABLE_CAT", + "TABLE_SCHEM", + "TABLE_NAME", + "GRANTOR", + "GRANTEE", + "PRIVILEGE", + "IS_GRANTABLE" + ); + + public static List VERSION_COLUMNS = Arrays.asList( + "SCOPE", + "COLUMN_NAME", + "DATA_TYPE", + "TYPE_NAME", + "COLUMN_SIZE", + "BUFFER_LENGTH", + "DECIMAL_DIGITS", + "PSEUDO_COLUMN" + ); + + public static List PRIMARY_KEYS = Arrays.asList( + "TABLE_CAT", + "TABLE_SCHEM", + "TABLE_NAME", + "COLUMN_NAME", + "KEY_SEQ", + "PK_NAME" + ); + + public static List FOREIGN_KEYS = Arrays.asList( + "PKTABLE_CAT", + "PKTABLE_SCHEM", + "PKTABLE_NAME", + "PKCOLUMN_NAME", + "FKTABLE_CAT", + "FKTABLE_SCHEM", + "FKTABLE_NAME", + "FKCOLUMN_NAME", + "KEY_SEQ", + "UPDATE_RULE", + "DELETE_RULE", + "FK_NAME", + "PK_NAME", + "DEFERRABILITY" + ); + + public static List TYPE_INFO = Arrays.asList( + "TYPE_NAME", + "DATA_TYPE", + "PRECISION", + "LITERAL_PREFIX", + "LITERAL_SUFFIX", + "CREATE_PARAMS", + "NULLABLE", + "CASE_SENSITIVE", + "SEARCHABLE", + "UNSIGNED_ATTRIBUTE", + "FIXED_PREC_SCALE", + "AUTO_INCREMENT", + "LOCAL_TYPE_NAME", + "MINIMUM_SCALE", + "MAXIMUM_SCALE", + "SQL_DATA_TYPE", + "SQL_DATETIME_SUB", + "NUM_PREC_RADIX" + ); + + public static List INDEX_INFO = Arrays.asList( + "TABLE_CAT", + "TABLE_SCHEM", + "TABLE_NAME", + "NON_UNIQUE", + "INDEX_QUALIFIER", + "INDEX_NAME", + "TYPE", + "ORDINAL_POSITION", + "COLUMN_NAME", + "ASC_OR_DESC", + "CARDINALITY", + "PAGES", + "FILTER_CONDITION" + ); + + public static List UDTS = Arrays.asList( + "TYPE_CAT", + "TYPE_SCHEM", + "TYPE_NAME", + "CLASS_NAME", + "DATA_TYPE", + "REMARKS", + "BASE_TYPE" + ); + + public static List SUPER_TYPES = Arrays.asList( + "TYPE_CAT", + "TYPE_SCHEM", + "TYPE_NAME", + "SUPERTYPE_CAT", + "SUPERTYPE_SCHEM", + "SUPERTYPE_NAME" + ); + + public static List SUPER_TABLES = Arrays.asList( + "TABLE_CAT", + "TABLE_SCHEM", + "TABLE_NAME", + "SUPERTABLE_NAME" + ); + + public static List FUNCTIONS = Arrays.asList( + "FUNCTION_CAT", + "FUNCTION_SCHEM", + "FUNCTION_NAME", + "REMARKS", + "FUNCTION_TYPE", + "SPECIFIC_NAME" + ); + + public static List FUNCTION_COLUMNS = Arrays.asList( + "FUNCTION_CAT", + "FUNCTION_SCHEM", + "FUNCTION_NAME", + "COLUMN_NAME", + "COLUMN_TYPE", + "DATA_TYPE", + "TYPE_NAME", + "PRECISION", + "LENGTH", + "SCALE", + "RADIX", + "NULLABLE", + "REMARKS", + "CHAR_OCTET_LENGTH", + "ORDINAL_POSITION", + "IS_NULLABLE", + "SPECIFIC_NAME" + ); + + public static List PSEUDO_COLUMNS = Arrays.asList( + "FUNCTION_CAT", + "FUNCTION_SCHEM", + "FUNCTION_NAME", + "COLUMN_NAME", + "COLUMN_TYPE", + "DATA_TYPE", + "TYPE_NAME", + "PRECISION", + "LENGTH", + "SCALE", + "RADIX", + "NULLABLE", + "REMARKS", + "CHAR_OCTET_LENGTH", + "ORDINAL_POSITION", + "IS_NULLABLE", + "SPECIFIC_NAME" + ); + + public static List ATTRIBUTES = Arrays.asList( + "TYPE_CAT", + "TYPE_SCHEM", + "TYPE_NAME", + "ATTR_NAME", + "DATA_TYPE", + "ATTR_TYPE_NAME", + "ATTR_SIZE", + "DECIMAL_DIGITS", + "NUM_PREC_RADIX", + "NULLABLE", + "REMARKS", + "ATTR_DEF", + "SQL_DATA_TYPE", + "SQL_DATETIME_SUB", + "CHAR_OCTET_LENGTH", + "ORDINAL_POSITION", + "IS_NULLABLE", + "SCOPE_CATALOG", + "SCOPE_SCHEMA", + "SCOPE_TABLE", + "SOURCE_DATA_TYPE" + ); + + public static List CLIENT_INFO_PROPERTIES = Arrays.asList( + "NAME", + "MAX_LEN", + "DEFAULT_VALUE", + "DESCRIPTION" + ); + + } + } diff --git a/src/test/java/org/tarantool/jdbc/JdbcConnectionIT.java b/src/test/java/org/tarantool/jdbc/JdbcConnectionIT.java index 9448a8c9..eca60d0d 100644 --- a/src/test/java/org/tarantool/jdbc/JdbcConnectionIT.java +++ b/src/test/java/org/tarantool/jdbc/JdbcConnectionIT.java @@ -17,14 +17,17 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; +import java.sql.ClientInfoStatus; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLClientInfoException; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.sql.Statement; +import java.util.Map; public class JdbcConnectionIT { @@ -443,4 +446,19 @@ public void testGeneratedKeys() throws SQLException { ); } + @Test + void testSetClientInfoProperties() { + String targetProperty = "ApplicationName"; + + SQLClientInfoException exception = assertThrows( + SQLClientInfoException.class, + () -> conn.setClientInfo(targetProperty, "TestApp") + ); + + Map failedProperties = exception.getFailedProperties(); + assertEquals(1, failedProperties.size()); + assertEquals(ClientInfoStatus.REASON_UNKNOWN_PROPERTY, failedProperties.get(targetProperty)); + } + } + diff --git a/src/test/java/org/tarantool/jdbc/JdbcDatabaseMetaDataIT.java b/src/test/java/org/tarantool/jdbc/JdbcDatabaseMetaDataIT.java index d4ea9f2b..28477a0b 100644 --- a/src/test/java/org/tarantool/jdbc/JdbcDatabaseMetaDataIT.java +++ b/src/test/java/org/tarantool/jdbc/JdbcDatabaseMetaDataIT.java @@ -75,6 +75,14 @@ public void tearDownTest() throws SQLException { testHelper.executeSql(CLEAN_SQL); } + @Test + public void testGetSupportedClientInfo() throws SQLException { + ResultSet rs = meta.getClientInfoProperties(); + assertNotNull(rs); + assertFalse(rs.next()); + rs.close(); + } + @Test public void testGetTableTypes() throws SQLException { ResultSet rs = meta.getTableTypes();