Skip to content

Commit

Permalink
implemented simple variant of client properties
Browse files Browse the repository at this point in the history
  • Loading branch information
chernser committed Nov 28, 2024
1 parent f330fef commit 4bf118e
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 39 deletions.
4 changes: 4 additions & 0 deletions client-v2/src/main/java/com/clickhouse/client/api/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -2117,6 +2117,10 @@ public void setDBRoles(Collection<String> dbRoles) {
this.configuration.get(ClientConfigProperties.SESSION_DB_ROLES.getKey())));
}

public void updateClientName(String name) {
this.configuration.put(ClientConfigProperties.CLIENT_NAME.getKey(), name);
}

private Collection<String> unmodifiableDbRolesView = Collections.emptyList();

/**
Expand Down
46 changes: 28 additions & 18 deletions jdbc-v2/src/main/java/com/clickhouse/jdbc/ConnectionImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@
import com.clickhouse.client.api.Client;
import com.clickhouse.client.api.query.GenericRecord;
import com.clickhouse.client.api.query.QuerySettings;
import com.clickhouse.jdbc.internal.ClientInfoProperties;
import com.clickhouse.jdbc.internal.JdbcConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Collection;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.Executor;

public class ConnectionImpl implements Connection, JdbcV2Wrapper {
Expand Down Expand Up @@ -169,7 +172,7 @@ public boolean isReadOnly() throws SQLException {
@Override
public void setCatalog(String catalog) throws SQLException {
checkOpen();
this.catalog = catalog;
// this.catalog = catalog; currently not supported
}

@Override
Expand Down Expand Up @@ -347,27 +350,34 @@ public boolean isValid(int timeout) throws SQLException {

@Override
public void setClientInfo(String name, String value) throws SQLClientInfoException {
// try {
// checkOpen();
// this.defaultQuerySettings.setOption(name, value);
// } catch (Exception e) {
// throw new SQLClientInfoException("Failed to set client info.", Collections.singletonMap(name, ClientInfoStatus.REASON_UNKNOWN), e);
// }
throw new SQLClientInfoException("Failed to set client info.", new HashMap<>(), new SQLFeatureNotSupportedException("setClientInfo not supported"));
if (ClientInfoProperties.APPLICATION_NAME.getKey().equals(name)) {
client.updateClientName(value);
}
// TODO: generate warning for unknown properties
}

@Override
public void setClientInfo(Properties properties) throws SQLClientInfoException {
// try {
// checkOpen();
// } catch (SQLException e) {
// throw new SQLClientInfoException("Failed to set client info.", new HashMap<>(), e);
// }
//
// for (Map.Entry<Object, Object> entry : properties.entrySet()) {
// setClientInfo(entry.getKey().toString(), entry.getValue().toString());
// }
throw new SQLClientInfoException("Failed to set client info.", new HashMap<>(), new SQLFeatureNotSupportedException("setClientInfo not supported"));
Set<String> toSet = new HashSet<>();
Set<String> toReset = new HashSet<>();
for (ClientInfoProperties p : ClientInfoProperties .values()) {
String key = p.getKey();
if (properties.containsKey(key)) {
toSet.add(key);
} else {
toReset.add(key);
}
}

// first we reset value
for (String key : toReset) {
setClientInfo(key, null);
}

// then we set value, so aliases will not clean values accidentally
for (String key : toSet) {
setClientInfo(key, properties.getProperty(key));
}
}

@Override
Expand Down
31 changes: 15 additions & 16 deletions jdbc-v2/src/main/java/com/clickhouse/jdbc/StatementImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,16 @@ public class StatementImpl implements Statement, JdbcV2Wrapper {
private List<String> batch;
private String lastQueryId;

public StatementImpl(ConnectionImpl connection) {
private String schema;

public StatementImpl(ConnectionImpl connection) throws SQLException {
this.connection = connection;
this.queryTimeout = 0;
this.closed = false;
this.currentResultSet = null;
this.metrics = null;
this.batch = new ArrayList<>();
this.schema = connection.getSchema(); // remember DB name
}

protected void checkClosed() throws SQLException {
Expand Down Expand Up @@ -107,7 +110,7 @@ protected static String parseJdbcEscapeSyntax(String sql) {
@Override
public ResultSet executeQuery(String sql) throws SQLException {
checkClosed();
return executeQuery(sql, connection.getDefaultQuerySettings());
return executeQuery(sql, new QuerySettings().setDatabase(schema));
}

public ResultSet executeQuery(String sql, QuerySettings settings) throws SQLException {
Expand Down Expand Up @@ -136,7 +139,7 @@ public ResultSet executeQuery(String sql, QuerySettings settings) throws SQLExce
@Override
public int executeUpdate(String sql) throws SQLException {
checkClosed();
return executeUpdate(sql, connection.getDefaultQuerySettings());
return executeUpdate(sql, new QuerySettings().setDatabase(schema));
}

public int executeUpdate(String sql, QuerySettings settings) throws SQLException {
Expand All @@ -148,18 +151,13 @@ public int executeUpdate(String sql, QuerySettings settings) throws SQLException

QuerySettings mergedSettings = QuerySettings.merge(connection.getDefaultQuerySettings(), settings);

try {
sql = parseJdbcEscapeSyntax(sql);
QueryResponse response;
if (queryTimeout == 0) {
response = connection.client.query(sql, mergedSettings).get();
} else {
response = connection.client.query(sql, mergedSettings).get(queryTimeout, TimeUnit.SECONDS);
}
sql = parseJdbcEscapeSyntax(sql);
try (QueryResponse response = queryTimeout == 0 ? connection.client.query(sql, mergedSettings).get()
: connection.client.query(sql, mergedSettings).get(queryTimeout, TimeUnit.SECONDS)) {

currentResultSet = null;
metrics = response.getMetrics();
lastQueryId = response.getQueryId();
response.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
Expand Down Expand Up @@ -249,16 +247,17 @@ public void setCursorName(String name) throws SQLException {
@Override
public boolean execute(String sql) throws SQLException {
checkClosed();
return execute(sql, new QuerySettings());
return execute(sql, new QuerySettings().setDatabase(schema));
}

public boolean execute(String sql, QuerySettings settings) throws SQLException {
private boolean execute(String sql, QuerySettings settings) throws SQLException {
checkClosed();
StatementType type = parseStatementType(sql);

if (type == StatementType.SELECT) {
executeQuery(sql, settings);
return true;
try (ResultSet rs = executeQuery(sql, settings)) {
return true;
}
} else if(type == StatementType.SET) {
//SET ROLE
List<String> tokens = JdbcUtils.tokenizeSQL(sql);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.clickhouse.jdbc.internal;

public enum ClientInfoProperties {

APPLICATION_NAME("ApplicationName", 255, "", "Client application name."),
;

private String key;
private int maxValue;

private String defaultValue;

private String description;

ClientInfoProperties(String key, int maxValue, String defaultValue, String description) {
this.key = key;
this.maxValue = maxValue;
this.defaultValue = defaultValue;
this.description = description;
}

public String getKey() {
return key;
}

public int getMaxValue() {
return maxValue;
}

public String getDefaultValue() {
return defaultValue;
}

public String getDescription() {
return description;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.clickhouse.jdbc.ConnectionImpl;
import com.clickhouse.jdbc.Driver;
import com.clickhouse.jdbc.JdbcV2Wrapper;
import com.clickhouse.jdbc.internal.ClientInfoProperties;
import com.clickhouse.jdbc.internal.JdbcUtils;
import com.clickhouse.logging.Logger;
import com.clickhouse.logging.LoggerFactory;
Expand All @@ -11,6 +12,9 @@
import java.sql.ResultSet;
import java.sql.RowIdLifetime;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class DatabaseMetaData implements java.sql.DatabaseMetaData, JdbcV2Wrapper {
private static final Logger log = LoggerFactory.getLogger(DatabaseMetaData.class);
Expand Down Expand Up @@ -1050,11 +1054,26 @@ public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
return false;
}

private static final String CLIENT_INFO_PROPERTIES_SQL = getClientInfoPropertiesSql();

private static String getClientInfoPropertiesSql() {
StringBuilder sql = new StringBuilder();
sql.append("SELECT c1 as NAME, c2 as MAX_LEN, c3 as DEFAULT_VALUE, c4 as DESCRIPTION FROM VALUES (");
Arrays.stream(ClientInfoProperties.values()).forEach(p -> {
sql.append("('").append(p.getKey()).append("', ");
sql.append(p.getMaxValue()).append(", ");
sql.append("'").append(p.getDefaultValue()).append("', ");
sql.append("'").append(p.getDescription()).append("'), ");
});
sql.setLength(sql.length() - 2);
sql.append(")");
return sql.toString();
}

@Override
public ResultSet getClientInfoProperties() throws SQLException {
//Return an empty result set with the required columns
log.warn("getClientInfoProperties is not supported and may return invalid results");
return connection.createStatement().executeQuery("SELECT NULL AS NAME, NULL AS MAX_LEN, NULL AS DEFAULT_VALUE, NULL AS DESCRIPTION");

return connection.createStatement().executeQuery(CLIENT_INFO_PROPERTIES_SQL);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.clickhouse.jdbc.metadata;

import com.clickhouse.jdbc.JdbcIntegrationTest;
import com.clickhouse.jdbc.internal.ClientInfoProperties;
import org.testng.Assert;
import org.testng.annotations.Ignore;
import org.testng.annotations.Test;
Expand Down Expand Up @@ -198,9 +199,14 @@ public void testGetClientInfoProperties() throws Exception {
try (Connection conn = getJdbcConnection()) {
DatabaseMetaData dbmd = conn.getMetaData();
try (ResultSet rs = dbmd.getClientInfoProperties()) {
Assert.assertTrue(rs.next());
for (ClientInfoProperties p : ClientInfoProperties.values()) {
Assert.assertTrue(rs.next());
Assert.assertEquals(rs.getString("NAME"), p.getKey());
Assert.assertEquals(rs.getInt("MAX_LEN"), p.getMaxValue());
Assert.assertEquals(rs.getString("DEFAULT_VALUE"), p.getDefaultValue());
Assert.assertEquals(rs.getString("DESCRIPTION"), p.getDescription());
}
}
}
Assert.fail("Not implemented");
}
}

0 comments on commit 4bf118e

Please sign in to comment.