Skip to content

Commit 4c02535

Browse files
authored
Merge pull request #1962 from ClickHouse/tweak-url-handling
Adjusting port handling
2 parents 5c1b7fa + e4927c8 commit 4c02535

File tree

5 files changed

+122
-45
lines changed

5 files changed

+122
-45
lines changed

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

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -235,20 +235,27 @@ public Builder() {
235235

236236
/**
237237
* Builds a client object with the provided configuration through URL parameters.
238-
*
239-
* @param url - URL formatted string with protocol, host, port, and client configuration settings.
238+
* (e.g. http://localhost:8123/someDatabase?user=default)
239+
* @param urlString - URL formatted string with protocol, host, port, and client configuration settings.
240240
* @return Client - a client object
241241
*/
242-
public Builder fromUrl(String url) {
242+
public Builder fromUrl(String urlString) {
243243
try {
244-
Map<String, String> urlProperties = HttpAPIClientHelper.parseUrlParameters(new java.net.URL(url));
245-
this.addEndpoint(url);
244+
URL url = new URL(urlString);
245+
Map<String, String> urlProperties = HttpAPIClientHelper.parseUrlParameters(url);
246+
247+
// Add the endpoint
248+
boolean secure = url.getProtocol().equalsIgnoreCase("https");
249+
int port = url.getPort();
250+
if (port == -1) {
251+
port = secure ? ClickHouseHttpProto.DEFAULT_HTTPS_PORT : ClickHouseHttpProto.DEFAULT_HTTP_PORT;
252+
}
253+
this.addEndpoint(Protocol.HTTP, url.getHost(), port, secure);
246254

247255
for (ClientConfigProperties properties: ClientConfigProperties.values()) {
248-
String key = properties.getKey().replace(ClientConfigProperties.SERVER_SETTING_PREFIX, "");//People wouldn't pass with prefix
249-
String value = urlProperties.get(key);
256+
String value = urlProperties.get(properties.getKey());
250257
if (value != null) {
251-
this.configuration.put(properties.getKey(), value);//We need to keep the original key
258+
this.configuration.put(properties.getKey(), value);
252259
}
253260
}
254261

client-v2/src/main/java/com/clickhouse/client/api/http/ClickHouseHttpProto.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,8 @@ public class ClickHouseHttpProto {
5858
public static final String QPARAM_QUERY_ID = "query_id";
5959

6060
public static final String QPARAM_ROLE = "role";
61+
62+
public static final int DEFAULT_HTTP_PORT = 8123;
63+
64+
public static final int DEFAULT_HTTPS_PORT = 8443;
6165
}

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

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.clickhouse.client.api.Client;
44
import com.clickhouse.client.api.data_formats.ClickHouseBinaryFormatReader;
5+
import com.clickhouse.client.api.query.GenericRecord;
56
import com.clickhouse.client.api.query.QueryResponse;
67
import com.clickhouse.client.api.query.QuerySettings;
78
import com.clickhouse.jdbc.internal.JdbcConfiguration;
@@ -67,16 +68,10 @@ public void setDefaultQuerySettings(QuerySettings settings) {
6768
}
6869

6970
private String getServerVersion() throws SQLException {
70-
try (QueryResponse response = client.query("SELECT version()").get(30, TimeUnit.SECONDS)) {
71-
// Create a reader to access the data in a convenient way
72-
ClickHouseBinaryFormatReader reader = client.newBinaryFormatReader(response);
73-
// Read the next record from stream and parse it as a string
74-
reader.next();
75-
return reader.getString(0);
76-
} catch (Exception e) {
77-
log.error("Failed to retrieve server version.", e);
78-
throw new SQLException("Failed to retrieve server version.", e);
79-
}
71+
GenericRecord result = client.queryAll("SELECT version() as server_version").stream()
72+
.findFirst().orElseThrow(() -> new SQLException("Failed to retrieve server version."));
73+
74+
return result.getString("server_version");
8075
}
8176

8277
public int getMajorVersion() throws SQLException {
@@ -125,7 +120,10 @@ public String nativeSQL(String sql) throws SQLException {
125120

126121
@Override
127122
public void setAutoCommit(boolean autoCommit) throws SQLException {
128-
throw new SQLFeatureNotSupportedException("setAutoCommit not supported");
123+
checkOpen();
124+
if (!autoCommit) {
125+
throw new SQLFeatureNotSupportedException("setAutoCommit = false not supported");
126+
}
129127
}
130128

131129
@Override

jdbc-v2/src/main/java/com/clickhouse/jdbc/internal/JdbcConfiguration.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.clickhouse.jdbc.internal;
22

3+
import com.clickhouse.client.api.http.ClickHouseHttpProto;
4+
35
import java.net.MalformedURLException;
46
import java.net.URL;
57
import java.sql.DriverPropertyInfo;
@@ -44,8 +46,8 @@ public boolean isDisableFrameworkDetection() {
4446
}
4547

4648
public JdbcConfiguration(String url, Properties info) {
47-
this.jdbcUrl = url;
48-
this.url = stripUrlPrefix(url);
49+
this.jdbcUrl = url;//Raw URL
50+
this.url = cleanUrl(url);
4951
this.user = info.getProperty("user", "default");
5052
this.password = info.getProperty("password", "");
5153
this.disableFrameworkDetection = Boolean.parseBoolean(info.getProperty("disable_frameworks_detection", "false"));
@@ -55,6 +57,22 @@ public static boolean acceptsURL(String url) {
5557
return url.startsWith(PREFIX_CLICKHOUSE) || url.startsWith(PREFIX_CLICKHOUSE_SHORT);
5658
}
5759

60+
private String cleanUrl(String url) {
61+
url = stripUrlPrefix(url);
62+
if (url.startsWith("//")) {
63+
url = "http:" + url;//Default to HTTP
64+
try {
65+
URL parsedUrl = new URL(url);
66+
if (parsedUrl.getPort() == ClickHouseHttpProto.DEFAULT_HTTPS_PORT) {//If port is 8443, switch to HTTPS
67+
url = "https:" + url;
68+
}
69+
} catch (MalformedURLException e) {
70+
throw new IllegalArgumentException("URL is not valid.", e);
71+
}
72+
}
73+
74+
return url;
75+
}
5876
private String stripUrlPrefix(String url) {
5977
if (url.startsWith(PREFIX_CLICKHOUSE)) {
6078
return url.substring(PREFIX_CLICKHOUSE.length());

jdbc-v2/src/test/java/com/clickhouse/jdbc/DataTypeTests.java

Lines changed: 74 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.sql.Connection;
1111
import java.sql.Date;
1212
import java.sql.DriverManager;
13+
import java.sql.PreparedStatement;
1314
import java.sql.ResultSet;
1415
import java.sql.SQLException;
1516
import java.sql.Statement;
@@ -46,7 +47,7 @@ private int insertData(String sql) throws SQLException {
4647
}
4748

4849
@Test
49-
public void testIntegerTypesSimpleStatement() throws SQLException {
50+
public void testIntegerTypes() throws SQLException {
5051
runQuery("CREATE TABLE test_integers (order Int8, "
5152
+ "int8 Int8, int16 Int16, int32 Int32, int64 Int64, int128 Int128, int256 Int256, "
5253
+ "uint8 UInt8, uint16 UInt16, uint32 UInt32, uint64 UInt64, uint128 UInt128, uint256 UInt256"
@@ -82,9 +83,23 @@ public void testIntegerTypesSimpleStatement() throws SQLException {
8283
BigInteger uint128 = new BigInteger(128, rand);
8384
BigInteger uint256 = new BigInteger(256, rand);
8485

85-
String sql = String.format("INSERT INTO test_integers VALUES ( 3, %d, %d, %d, %d, %s, %s, %d, %d, %d, %d, %s, %s)",
86-
int8, int16, int32, int64, int128, int256, uint8, uint16, uint32, uint64, uint128, uint256);
87-
insertData(sql);
86+
try (Connection conn = getConnection()) {
87+
try (PreparedStatement stmt = conn.prepareStatement("INSERT INTO test_integers VALUES ( 3, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")) {
88+
stmt.setInt(1, int8);
89+
stmt.setInt(2, int16);
90+
stmt.setInt(3, int32);
91+
stmt.setLong(4, int64);
92+
stmt.setBigDecimal(5, new BigDecimal(int128));
93+
stmt.setBigDecimal(6, new BigDecimal(int256));
94+
stmt.setInt(7, uint8);
95+
stmt.setInt(8, uint16);
96+
stmt.setLong(9, uint32);
97+
stmt.setBigDecimal(10, new BigDecimal(uint64));
98+
stmt.setBigDecimal(11, new BigDecimal(uint128));
99+
stmt.setBigDecimal(12, new BigDecimal(uint256));
100+
stmt.executeUpdate();
101+
}
102+
}
88103

89104
// Check the results
90105
try (Connection conn = getConnection()) {
@@ -139,7 +154,7 @@ public void testIntegerTypesSimpleStatement() throws SQLException {
139154
}
140155

141156
@Test
142-
public void testDecimalTypesSimpleStatement() throws SQLException {
157+
public void testDecimalTypes() throws SQLException {
143158
runQuery("CREATE TABLE test_decimals (order Int8, "
144159
+ "dec Decimal(9, 2), dec32 Decimal32(4), dec64 Decimal64(8), dec128 Decimal128(18), dec256 Decimal256(18)"
145160
+ ") ENGINE = Memory");
@@ -163,9 +178,17 @@ public void testDecimalTypesSimpleStatement() throws SQLException {
163178
BigDecimal dec128 = new BigDecimal(new BigInteger(20, rand) + "." + rand.nextLong(100000000000000000L, 1000000000000000000L));
164179
BigDecimal dec256 = new BigDecimal(new BigInteger(58, rand) + "." + rand.nextLong(100000000000000000L, 1000000000000000000L));
165180

166-
String sql = String.format("INSERT INTO test_decimals VALUES ( 3, %s, %s, %s, %s, %s)",
167-
dec, dec32, dec64, dec128, dec256);
168-
insertData(sql);
181+
try (Connection conn = getConnection()) {
182+
try (PreparedStatement stmt = conn.prepareStatement("INSERT INTO test_decimals VALUES ( 3, ?, ?, ?, ?, ?)")) {
183+
stmt.setBigDecimal(1, dec);
184+
stmt.setBigDecimal(2, dec32);
185+
stmt.setBigDecimal(3, dec64);
186+
stmt.setBigDecimal(4, dec128);
187+
stmt.setBigDecimal(5, dec256);
188+
stmt.executeUpdate();
189+
}
190+
}
191+
169192

170193
// Check the results
171194
try (Connection conn = getConnection()) {
@@ -199,7 +222,7 @@ public void testDecimalTypesSimpleStatement() throws SQLException {
199222
}
200223

201224
@Test
202-
public void testDateTypesSimpleStatement() throws SQLException {
225+
public void testDateTypes() throws SQLException {
203226
runQuery("CREATE TABLE test_dates (order Int8, "
204227
+ "date Date, date32 Date32, " +
205228
"dateTime DateTime, dateTime32 DateTime32, " +
@@ -230,9 +253,18 @@ public void testDateTypesSimpleStatement() throws SQLException {
230253
java.sql.Timestamp dateTime646 = new java.sql.Timestamp(now);
231254
java.sql.Timestamp dateTime649 = new java.sql.Timestamp(now);
232255

233-
String sql = String.format("INSERT INTO test_dates VALUES ( 3, '%s', '%s', '%s', '%s', '%s', '%s', '%s' )",
234-
date, date32, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(dateTime), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(dateTime32), dateTime643, dateTime646, dateTime649);
235-
insertData(sql);
256+
try (Connection conn = getConnection()) {
257+
try (PreparedStatement stmt = conn.prepareStatement("INSERT INTO test_dates VALUES ( 4, ?, ?, ?, ?, ?, ?, ?)")) {
258+
stmt.setDate(1, date);
259+
stmt.setDate(2, date32);
260+
stmt.setTimestamp(3, dateTime);
261+
stmt.setTimestamp(4, dateTime32);
262+
stmt.setTimestamp(5, dateTime643);
263+
stmt.setTimestamp(6, dateTime646);
264+
stmt.setTimestamp(7, dateTime649);
265+
stmt.executeUpdate();
266+
}
267+
}
236268

237269
// Check the results
238270
try (Connection conn = getConnection()) {
@@ -272,7 +304,7 @@ public void testDateTypesSimpleStatement() throws SQLException {
272304
}
273305

274306
@Test
275-
public void testStringTypesSimpleStatement() throws SQLException {
307+
public void testStringTypes() throws SQLException {
276308
runQuery("CREATE TABLE test_strings (order Int8, "
277309
+ "str String, fixed FixedString(6), "
278310
+ "enum Enum8('a' = 6, 'b' = 7, 'c' = 8), enum8 Enum8('a' = 1, 'b' = 2, 'c' = 3), enum16 Enum16('a' = 1, 'b' = 2, 'c' = 3), "
@@ -292,9 +324,20 @@ public void testStringTypesSimpleStatement() throws SQLException {
292324
String ipv4 = rand.nextInt(256) + "." + rand.nextInt(256) + "." + rand.nextInt(256) + "." + rand.nextInt(256);
293325
String ipv6 = "2001:adb8:85a3:1:2:8a2e:370:7334";
294326

295-
String sql = String.format("INSERT INTO test_strings VALUES ( 1, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )",
296-
str, fixed, enum8, enum8, enum16, uuid, ipv4, ipv6);
297-
insertData(sql);
327+
328+
try (Connection conn = getConnection()) {
329+
try (PreparedStatement stmt = conn.prepareStatement("INSERT INTO test_strings VALUES ( 1, ?, ?, ?, ?, ?, ?, ?, ? )")) {
330+
stmt.setString(1, str);
331+
stmt.setString(2, fixed);
332+
stmt.setString(3, enum8);
333+
stmt.setString(4, enum8);
334+
stmt.setString(5, enum16);
335+
stmt.setString(6, uuid);
336+
stmt.setString(7, ipv4);
337+
stmt.setString(8, ipv6);
338+
stmt.executeUpdate();
339+
}
340+
}
298341

299342
// Check the results
300343
try (Connection conn = getConnection()) {
@@ -317,7 +360,7 @@ public void testStringTypesSimpleStatement() throws SQLException {
317360
}
318361

319362
@Test
320-
public void testFloatTypesSimpleStatement() throws SQLException {
363+
public void testFloatTypes() throws SQLException {
321364
runQuery("CREATE TABLE test_floats (order Int8, "
322365
+ "float32 Float32, float64 Float64"
323366
+ ") ENGINE = Memory");
@@ -336,9 +379,13 @@ public void testFloatTypesSimpleStatement() throws SQLException {
336379
Float float32 = rand.nextFloat();
337380
Double float64 = rand.nextDouble();
338381

339-
String sql = String.format("INSERT INTO test_floats VALUES ( 3, %s, %s )",
340-
float32, float64);
341-
insertData(sql);
382+
try (Connection conn = getConnection()) {
383+
try (PreparedStatement stmt = conn.prepareStatement("INSERT INTO test_floats VALUES ( 3, ?, ? )")) {
384+
stmt.setFloat(1, float32);
385+
stmt.setDouble(2, float64);
386+
stmt.executeUpdate();
387+
}
388+
}
342389

343390
// Check the results
344391
try (Connection conn = getConnection()) {
@@ -363,7 +410,7 @@ public void testFloatTypesSimpleStatement() throws SQLException {
363410
}
364411

365412
@Test
366-
public void testBooleanTypesSimpleStatement() throws SQLException {
413+
public void testBooleanTypes() throws SQLException {
367414
runQuery("CREATE TABLE test_booleans (order Int8, "
368415
+ "bool Boolean"
369416
+ ") ENGINE = Memory");
@@ -375,9 +422,12 @@ public void testBooleanTypesSimpleStatement() throws SQLException {
375422

376423
boolean bool = rand.nextBoolean();
377424

378-
String sql = String.format("INSERT INTO test_booleans VALUES ( 1, %s )",
379-
bool);
380-
insertData(sql);
425+
try (Connection conn = getConnection()) {
426+
try (PreparedStatement stmt = conn.prepareStatement("INSERT INTO test_booleans VALUES ( 1, ? )")) {
427+
stmt.setBoolean(1, bool);
428+
stmt.executeUpdate();
429+
}
430+
}
381431

382432
// Check the results
383433
try (Connection conn = getConnection()) {

0 commit comments

Comments
 (0)