Skip to content

Commit fe687bc

Browse files
authored
Merge pull request #2008 from ClickHouse/v2_process_jdbc_properties
[jdbc-v2] JDBC Properties configuration
2 parents d5d1255 + f0336f7 commit fe687bc

File tree

16 files changed

+493
-139
lines changed

16 files changed

+493
-139
lines changed

client-v2/src/main/java/com/clickhouse/client/api/Client.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ public void close() {
209209
if (oldClient != null) {
210210
oldClient.close();
211211
}
212+
213+
if (httpClientHelper != null) {
214+
httpClientHelper.close();
215+
}
212216
}
213217

214218
public static class Builder {
@@ -290,7 +294,7 @@ public Builder addEndpoint(String endpoint) {
290294
throw new IllegalArgumentException("Only HTTP and HTTPS protocols are supported");
291295
}
292296
} catch (java.net.MalformedURLException e) {
293-
throw new IllegalArgumentException("Endpoint should be a valid URL string", e);
297+
throw new IllegalArgumentException("Endpoint should be a valid URL string, but was " + endpoint, e);
294298
}
295299
return this;
296300
}
@@ -940,6 +944,16 @@ public Builder setClientName(String clientName) {
940944
return this;
941945
}
942946

947+
/**
948+
* Sets client options from provided map. Values are copied as is
949+
* @param options - map of client options
950+
* @return same instance of the builder
951+
*/
952+
public Builder setOptions(Map<String, String> options) {
953+
this.configuration.putAll(options);
954+
return this;
955+
}
956+
943957
public Client build() {
944958
setDefaults();
945959

@@ -950,7 +964,7 @@ public Client build() {
950964
// check if username and password are empty. so can not initiate client?
951965
if (!this.configuration.containsKey("access_token") &&
952966
(!this.configuration.containsKey("user") || !this.configuration.containsKey("password")) &&
953-
!MapUtils.getFlag(this.configuration, "ssl_authentication")) {
967+
!MapUtils.getFlag(this.configuration, "ssl_authentication", false)) {
954968
throw new IllegalArgumentException("Username and password (or access token, or SSL authentication) are required");
955969
}
956970

@@ -2105,6 +2119,10 @@ public Set<String> getEndpoints() {
21052119
return Collections.unmodifiableSet(endpoints);
21062120
}
21072121

2122+
public String getUser() {
2123+
return this.configuration.get(ClientConfigProperties.USER.getKey());
2124+
}
2125+
21082126
/**
21092127
* Sets list of DB roles that should be applied to each query.
21102128
*

client-v2/src/main/java/com/clickhouse/client/api/ClientConfigProperties.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ public enum ClientConfigProperties {
1717

1818
HTTP_USE_BASIC_AUTH("http_use_basic_auth"),
1919

20-
USER("user"),
20+
USER("user", "default"),
2121

22-
PASSWORD("password"),
22+
PASSWORD("password", ""),
2323

2424
/**
2525
* Maximum number of active connection in internal connection pool.
2626
*/
27-
HTTP_MAX_OPEN_CONNECTIONS("max_open_connections"),
27+
HTTP_MAX_OPEN_CONNECTIONS("max_open_connections", "10"),
2828

2929
/**
3030
* HTTP keep-alive timeout override.
@@ -59,7 +59,7 @@ public enum ClientConfigProperties {
5959

6060
SOCKET_LINGER_OPT("socket_linger"),
6161

62-
DATABASE("database"),
62+
DATABASE("database", "default"),
6363

6464
COMPRESS_SERVER_RESPONSE("compress"), // actually a server setting, but has client effect too
6565

@@ -118,14 +118,37 @@ public enum ClientConfigProperties {
118118

119119
private String key;
120120

121+
private String defaultValue;
122+
123+
private List<String> choices;
124+
125+
121126
ClientConfigProperties(String key) {
127+
this(key, null, Collections.emptyList());
128+
}
129+
130+
ClientConfigProperties(String key, String defaultValue) {
131+
this(key, defaultValue, Collections.emptyList());
132+
}
133+
134+
ClientConfigProperties(String key, String defaultValue, List<String> choices) {
122135
this.key = key;
136+
this.defaultValue = defaultValue;
137+
this.choices = Collections.unmodifiableList(choices);
123138
}
124139

125140
public String getKey() {
126141
return key;
127142
}
128143

144+
public List<String> getChoices() {
145+
return choices;
146+
}
147+
148+
public String getDefaultValue() {
149+
return defaultValue;
150+
}
151+
129152
public static final String HTTP_HEADER_PREFIX = "http_header_";
130153

131154
public static final String SERVER_SETTING_PREFIX = "clickhouse_setting_";

client-v2/src/main/java/com/clickhouse/client/api/data_formats/internal/AbstractBinaryFormatReader.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ public boolean hasValue(int colIndex) {
518518

519519
@Override
520520
public boolean hasValue(String colName) {
521+
getSchema().getColumnByName(colName);
521522
return currentRecord.containsKey(colName);
522523
}
523524

client-v2/src/main/java/com/clickhouse/client/api/internal/HttpAPIClientHelper.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.apache.hc.core5.http.impl.io.DefaultHttpResponseParserFactory;
4343
import org.apache.hc.core5.http.io.SocketConfig;
4444
import org.apache.hc.core5.http.io.entity.EntityTemplate;
45+
import org.apache.hc.core5.io.CloseMode;
4546
import org.apache.hc.core5.io.IOCallback;
4647
import org.apache.hc.core5.net.URIBuilder;
4748
import org.apache.hc.core5.pool.PoolConcurrencyPolicy;
@@ -639,4 +640,8 @@ public static Map<String, String> parseUrlParameters(URL url) {
639640

640641
return params;
641642
}
643+
644+
public void close() {
645+
httpClient.close(CloseMode.IMMEDIATE);
646+
}
642647
}

client-v2/src/main/java/com/clickhouse/client/api/internal/ServerSettings.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,14 @@ public final class ServerSettings {
2222
*/
2323
public static final String OUTPUT_FORMAT_BINARY_WRITE_JSON_AS_STRING = "output_format_binary_write_json_as_string";
2424

25+
/**
26+
* Limit number of rows in a result set
27+
*/
28+
public static final String MAX_RESULT_ROWS = "max_result_rows";
29+
30+
/**
31+
* Defines server response if result set exceeded a limit set by {@code max_result_rows}.
32+
* Possible values are 'throw' or 'break'. Default is 'throw'
33+
*/
34+
public static final String RESULT_OVERFLOW_MODE = "result_overflow_mode";
2535
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.clickhouse.client.api.metadata;
2+
3+
import com.clickhouse.client.api.ClientException;
4+
5+
public class NoSuchColumnException extends ClientException {
6+
7+
public NoSuchColumnException(String message) {
8+
super(message);
9+
}
10+
}

client-v2/src/main/java/com/clickhouse/client/api/metadata/TableSchema.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.clickhouse.client.api.metadata;
22

3+
import com.clickhouse.client.api.ClientException;
34
import com.clickhouse.data.ClickHouseColumn;
45

56
import java.util.ArrayList;
@@ -87,20 +88,22 @@ public void addColumn(String name, String type, String defaultType) {
8788
}
8889

8990
public ClickHouseColumn getColumnByName(String name) {
90-
for (ClickHouseColumn column : columns) {
91-
if (column.getColumnName().equalsIgnoreCase(name)) {
92-
return column;//TODO: Try to deep clone the column rather than reference pass
93-
}
94-
}
95-
96-
return null;
91+
return columns.get(nameToIndex(name));
9792
}
9893

9994
public String indexToName(int index) {
100-
return columns.get(index).getColumnName();
95+
try {
96+
return columns.get(index).getColumnName();
97+
} catch (IndexOutOfBoundsException e) {
98+
throw new NoSuchColumnException("Result has no column with index = " + index);
99+
}
101100
}
102101

103102
public int nameToIndex(String name) {
103+
Integer index = colIndex.get(name);
104+
if (index == null) {
105+
throw new NoSuchColumnException("Result has no column with name '" + name + "'");
106+
}
104107
return colIndex.get(name).intValue();
105108
}
106109

jdbc-v2/src/main/java/com/clickhouse/jdbc/ConnectionImpl.java

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.clickhouse.jdbc.internal.DriverProperties;
99
import com.clickhouse.jdbc.internal.JdbcConfiguration;
1010
import com.clickhouse.jdbc.internal.ExceptionUtils;
11+
import com.clickhouse.jdbc.internal.JdbcConfiguration;
1112
import org.slf4j.Logger;
1213
import org.slf4j.LoggerFactory;
1314

@@ -68,24 +69,13 @@ public ConnectionImpl(String url, Properties info) throws SQLException {
6869
clientName += " (" + detectedFrameworks + ")";
6970
}
7071

71-
this.client = new Client.Builder()
72-
.fromUrl(this.config.getUrl())//URL without prefix
73-
.setUsername(config.getUser())
74-
.setPassword(config.getPassword())
72+
this.client = this.config.applyClientProperties(new Client.Builder())
7573
.setClientName(clientName)
7674
.build();
77-
this.schema = client.getDefaultDatabase(); // TODO: fix in properties handling?
75+
this.schema = client.getDefaultDatabase();
7876
this.defaultQuerySettings = new QuerySettings();
7977

80-
this.metadata = new com.clickhouse.jdbc.metadata.DatabaseMetaData(this, false);
81-
}
82-
83-
public String getUser() {
84-
return config.getUser();
85-
}
86-
87-
public String getURL() {
88-
return url;
78+
this.metadata = new com.clickhouse.jdbc.metadata.DatabaseMetaData(this, false, url);
8979
}
9080

9181
public QuerySettings getDefaultQuerySettings() {
@@ -506,6 +496,14 @@ public void setShardingKey(ShardingKey shardingKey) throws SQLException {
506496
Connection.super.setShardingKey(shardingKey);
507497
}
508498

499+
/**
500+
* Returns instance of the client used to execute queries by this connection.
501+
* @return - client instance
502+
*/
503+
public Client getClient() {
504+
return client;
505+
}
506+
509507
private void checkOpen() throws SQLException {
510508
if (isClosed()) {
511509
throw new SQLException("Connection is closed", ExceptionUtils.SQL_STATE_CONNECTION_EXCEPTION);

jdbc-v2/src/main/java/com/clickhouse/jdbc/Driver.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.clickhouse.jdbc;
22

33

4+
import com.clickhouse.client.api.ClientConfigProperties;
45
import com.clickhouse.jdbc.internal.JdbcConfiguration;
56
import com.clickhouse.jdbc.internal.ExceptionUtils;
67
import org.slf4j.Logger;
@@ -130,7 +131,7 @@ public boolean acceptsURL(String url) throws SQLException {
130131

131132
@Override
132133
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
133-
return JdbcConfiguration.getDriverPropertyInfo(info).toArray(new DriverPropertyInfo[0]);
134+
return new JdbcConfiguration(url, info).getDriverPropertyInfo().toArray(new DriverPropertyInfo[0]);
134135
}
135136

136137
public static int getDriverMajorVersion() {
@@ -156,6 +157,10 @@ public boolean jdbcCompliant() {
156157
return false;
157158
}
158159

160+
public static String chSettingKey(String key) {
161+
return ClientConfigProperties.serverSetting(key);
162+
}
163+
159164
@Override
160165
public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
161166
throw new SQLFeatureNotSupportedException("Method not supported", ExceptionUtils.SQL_STATE_FEATURE_NOT_SUPPORTED);
Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,54 @@
11
package com.clickhouse.jdbc.internal;
22

3+
import java.util.Collections;
4+
import java.util.List;
5+
36
/**
4-
* JDBC driver specific properties. Do not include any ClickHouse client properties here.
7+
* JDBC driver specific properties. Should not include any of ClientConfigProperties.
8+
* Processing logic should be the follows
9+
* 1. If property is among DriverProperties then Driver handles it specially and will not pass to a client
10+
* 2. If property is not among DriverProperties then it is passed to a client
511
*/
612
public enum DriverProperties {
713

814
IGNORE_UNSUPPORTED_VALUES("jdbc_ignore_unsupported_values", ""),
915
SCHEMA_TERM("jdbc_schema_term", ""),
10-
PLACEHOLDER("placeholder", "Placeholder for unknown properties");
16+
/**
17+
* Indicates if driver should create a secure connection over SSL/TLS
18+
*/
19+
SECURE_CONNECTION("ssl", "false"),
20+
21+
/**
22+
* query settings to be passed along with query operation.
23+
* {@see com.clickhouse.client.api.query.QuerySettings}
24+
*/
25+
DEFAULT_QUERY_SETTINGS("default_query_settings", null);
1126

1227
private final String key;
1328

14-
private final String description;
29+
private final String defaultValue;
30+
31+
private final List<String> choices;
32+
33+
DriverProperties(String key, String defaultValue) {
34+
this(key, defaultValue, Collections.emptyList());
35+
}
1536

16-
DriverProperties(String key, String description) {
37+
DriverProperties(String key, String defaultValue, List<String> choices) {
1738
this.key = key;
18-
this.description = description;
39+
this.defaultValue = defaultValue;
40+
this.choices = choices;
1941
}
2042

2143
public String getKey() {
2244
return key;
2345
}
46+
47+
public String getDefaultValue() {
48+
return defaultValue;
49+
}
50+
51+
public List<String> getChoices() {
52+
return choices;
53+
}
2454
}

0 commit comments

Comments
 (0)