Skip to content

Commit 27f8a3d

Browse files
authored
Merge pull request #1965 from ClickHouse/Adjusting-jdbc
Adding types, adjusting constructors
2 parents 4c02535 + 094d238 commit 27f8a3d

File tree

12 files changed

+201
-138
lines changed

12 files changed

+201
-138
lines changed

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

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
package com.clickhouse.jdbc;
22

33
import com.clickhouse.client.api.Client;
4-
import com.clickhouse.client.api.data_formats.ClickHouseBinaryFormatReader;
54
import com.clickhouse.client.api.query.GenericRecord;
6-
import com.clickhouse.client.api.query.QueryResponse;
75
import com.clickhouse.client.api.query.QuerySettings;
86
import com.clickhouse.jdbc.internal.JdbcConfiguration;
97
import org.slf4j.Logger;
108
import org.slf4j.LoggerFactory;
119

1210
import java.sql.*;
11+
import java.util.Collections;
12+
import java.util.HashMap;
13+
import java.util.List;
1314
import java.util.Map;
1415
import java.util.Properties;
1516
import java.util.concurrent.Executor;
16-
import java.util.concurrent.TimeUnit;
1717

1818
public class ConnectionImpl implements Connection, JdbcV2Wrapper {
1919
private static final Logger log = LoggerFactory.getLogger(ConnectionImpl.class);
@@ -47,7 +47,6 @@ public ConnectionImpl(String url, Properties info) {
4747
.setPassword(config.getPassword())
4848
.setClientName(clientName)
4949
.build();
50-
5150
this.defaultQuerySettings = new QuerySettings();
5251
}
5352

@@ -166,8 +165,8 @@ public DatabaseMetaData getMetaData() throws SQLException {
166165
@Override
167166
public void setReadOnly(boolean readOnly) throws SQLException {
168167
checkOpen();
169-
if (!readOnly) {
170-
throw new SQLFeatureNotSupportedException("read-only=false unsupported");
168+
if (readOnly) {
169+
throw new SQLFeatureNotSupportedException("read-only=true unsupported");
171170
}
172171
}
173172

@@ -358,30 +357,53 @@ public boolean isValid(int timeout) throws SQLException {
358357

359358
@Override
360359
public void setClientInfo(String name, String value) throws SQLClientInfoException {
361-
throw new SQLClientInfoException("ClientInfo not supported", null);
360+
// try {
361+
// checkOpen();
362+
// this.defaultQuerySettings.setOption(name, value);
363+
// } catch (Exception e) {
364+
// throw new SQLClientInfoException("Failed to set client info.", Collections.singletonMap(name, ClientInfoStatus.REASON_UNKNOWN), e);
365+
// }
366+
throw new SQLClientInfoException("Failed to set client info.", new HashMap<>(), new SQLFeatureNotSupportedException("setClientInfo not supported"));
362367
}
363368

364369
@Override
365370
public void setClientInfo(Properties properties) throws SQLClientInfoException {
366-
throw new SQLClientInfoException("ClientInfo not supported", null);
371+
// try {
372+
// checkOpen();
373+
// } catch (SQLException e) {
374+
// throw new SQLClientInfoException("Failed to set client info.", new HashMap<>(), e);
375+
// }
376+
//
377+
// for (Map.Entry<Object, Object> entry : properties.entrySet()) {
378+
// setClientInfo(entry.getKey().toString(), entry.getValue().toString());
379+
// }
380+
throw new SQLClientInfoException("Failed to set client info.", new HashMap<>(), new SQLFeatureNotSupportedException("setClientInfo not supported"));
367381
}
368382

369383
@Override
370384
public String getClientInfo(String name) throws SQLException {
371385
checkOpen();
372-
return null;
386+
// Object value = this.defaultQuerySettings.getAllSettings().get(name);
387+
// return value == null ? null : String.valueOf(value);
388+
throw new SQLFeatureNotSupportedException("getClientInfo not supported");
373389
}
374390

375391
@Override
376392
public Properties getClientInfo() throws SQLException {
377393
checkOpen();
378-
return new Properties();
394+
// Properties clientInfo = new Properties();
395+
// clientInfo.putAll(this.defaultQuerySettings.getAllSettings());
396+
// return clientInfo;
397+
throw new SQLFeatureNotSupportedException("getClientInfo not supported");
379398
}
380399

381400
@Override
382401
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
383-
//TODO: Should this be supported?
384-
return null;
402+
try {
403+
return new com.clickhouse.jdbc.types.Array(List.of(elements));
404+
} catch (Exception e) {
405+
throw new SQLException("Failed to create array", e);
406+
}
385407
}
386408

387409
@Override

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
import java.util.logging.Logger;
1212

1313
public class DataSourceImpl implements DataSource, JdbcV2Wrapper {
14+
private static final Logger log = Logger.getLogger(DataSourceImpl.class.getName());
1415
private String url;
1516
private Properties info;
16-
private Driver driver;
17+
private final Driver driver;
18+
private PrintWriter logWriter;
1719

1820
public void setUrl(String url) {
1921
this.url = url;
@@ -24,22 +26,20 @@ private Properties getProperties() {
2426
copy.putAll(info);
2527
return copy;
2628
}
29+
2730
public void setProperties(Properties info) {
2831
this.info = info;
2932
}
3033

31-
public DataSourceImpl() {
34+
35+
public DataSourceImpl() {//No-arg constructor required by the standard
3236
this(null, new Properties());
3337
}
3438

35-
public DataSourceImpl(String url) {
36-
this(url, new Properties());
37-
}
38-
3939
public DataSourceImpl(String url, Properties info) {
4040
this.url = url;
4141
this.info = info;
42-
this.driver = new Driver();
42+
this.driver = new Driver(this);
4343
}
4444

4545
@Override
@@ -58,12 +58,12 @@ public Connection getConnection(String username, String password) throws SQLExce
5858

5959
@Override
6060
public PrintWriter getLogWriter() throws SQLException {
61-
throw new SQLFeatureNotSupportedException("Method not supported");
61+
return logWriter;
6262
}
6363

6464
@Override
6565
public void setLogWriter(PrintWriter out) throws SQLException {
66-
throw new SQLFeatureNotSupportedException("Method not supported");
66+
logWriter = out;
6767
}
6868

6969
@Override

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

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
package com.clickhouse.jdbc;
22

3-
import java.sql.*;
4-
import java.util.*;
53

64
import com.clickhouse.jdbc.internal.JdbcConfiguration;
75
import org.slf4j.Logger;
86
import org.slf4j.LoggerFactory;
97

8+
import java.sql.Connection;
9+
import java.sql.DriverManager;
10+
import java.sql.DriverPropertyInfo;
11+
import java.sql.SQLException;
12+
import java.sql.SQLFeatureNotSupportedException;
13+
import java.util.Arrays;
14+
import java.util.LinkedHashSet;
15+
import java.util.List;
16+
import java.util.Properties;
17+
import java.util.Set;
18+
1019
/**
1120
* JDBC driver for ClickHouse.
1221
*/
1322
public class Driver implements java.sql.Driver {
1423
private static final Logger log = LoggerFactory.getLogger(Driver.class);
1524
public static final String driverVersion;
25+
private final DataSourceImpl dataSource;
1626

1727
public static String frameworksDetected = null;
1828
public static class FrameworksDetection {
@@ -54,6 +64,14 @@ public static String getFrameworksDetected() {
5464
//load(); //Commented out to avoid loading the driver multiple times, because we're referenced in V1
5565
}
5666

67+
public Driver() {
68+
this.dataSource = null;
69+
}
70+
71+
public Driver(DataSourceImpl dataSourceImpl) {
72+
this.dataSource = dataSourceImpl;
73+
}
74+
5775
public static void load() {
5876
try {
5977
DriverManager.registerDriver(new Driver());
@@ -74,6 +92,9 @@ public static void unload() {
7492

7593
@Override
7694
public Connection connect(String url, Properties info) throws SQLException {
95+
if (!acceptsURL(url)) {
96+
return null;
97+
}
7798
return new ConnectionImpl(url, info);
7899
}
79100

@@ -84,9 +105,6 @@ public boolean acceptsURL(String url) throws SQLException {
84105

85106
@Override
86107
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
87-
// if (!JdbcConfiguration.acceptsURL(url)) {
88-
// return new DriverPropertyInfo[0];
89-
// }
90108
return new DriverPropertyInfo[0];
91109
}
92110

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

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,25 @@
77
import java.io.Reader;
88
import java.math.BigDecimal;
99
import java.net.URL;
10-
import java.sql.*;
10+
import java.sql.Array;
11+
import java.sql.Blob;
12+
import java.sql.Clob;
13+
import java.sql.Date;
14+
import java.sql.JDBCType;
15+
import java.sql.NClob;
16+
import java.sql.ParameterMetaData;
17+
import java.sql.PreparedStatement;
18+
import java.sql.Ref;
19+
import java.sql.ResultSet;
20+
import java.sql.ResultSetMetaData;
21+
import java.sql.RowId;
22+
import java.sql.SQLException;
23+
import java.sql.SQLFeatureNotSupportedException;
24+
import java.sql.SQLType;
25+
import java.sql.SQLXML;
26+
import java.sql.Time;
27+
import java.sql.Timestamp;
28+
import java.sql.Types;
1129
import java.time.LocalDate;
1230
import java.time.LocalDateTime;
1331
import java.time.LocalTime;
@@ -16,6 +34,7 @@
1634
import java.time.format.DateTimeFormatterBuilder;
1735
import java.time.temporal.ChronoField;
1836
import java.util.Calendar;
37+
import java.util.Collection;
1938
import java.util.GregorianCalendar;
2039
import java.util.Map;
2140

@@ -439,7 +458,7 @@ private static String encodeObject(Object x) throws SQLException {
439458
if (x == null) {
440459
return "NULL";
441460
} else if (x instanceof String) {
442-
return "'" + x + "'";
461+
return "'" + escapeString((String) x) + "'";
443462
} else if (x instanceof Boolean) {
444463
return (Boolean) x ? "1" : "0";
445464
} else if (x instanceof Date) {
@@ -454,8 +473,28 @@ private static String encodeObject(Object x) throws SQLException {
454473
return "'" + DATETIME_FORMATTER.format(((Timestamp) x).toLocalDateTime()) + "'";
455474
} else if (x instanceof LocalDateTime) {
456475
return "'" + DATETIME_FORMATTER.format((LocalDateTime) x) + "'";
476+
} else if (x instanceof Array) {
477+
StringBuilder listString = new StringBuilder();
478+
listString.append("[");
479+
for (Object item : (Object[])((Array) x).getArray()) {
480+
listString.append(encodeObject(item)).append(", ");
481+
}
482+
listString.delete(listString.length() - 2, listString.length());
483+
listString.append("]");
484+
485+
return listString.toString();
486+
} else if (x instanceof Collection) {
487+
StringBuilder listString = new StringBuilder();
488+
listString.append("[");
489+
for (Object item : (Collection<?>) x) {
490+
listString.append(encodeObject(item)).append(", ");
491+
}
492+
listString.delete(listString.length() - 2, listString.length());
493+
listString.append("]");
494+
495+
return listString.toString();
457496
} else if (x instanceof Map) {
458-
Map tmpMap = (Map) x;
497+
Map<?, ?> tmpMap = (Map<?, ?>) x;
459498
StringBuilder mapString = new StringBuilder();
460499
mapString.append("{");
461500
for (Object key : tmpMap.keySet()) {
@@ -473,7 +512,7 @@ private static String encodeObject(Object x) throws SQLException {
473512
while ((len = reader.read(buffer)) != -1) {
474513
sb.append(buffer, 0, len);
475514
}
476-
return "'" + sb + "'";
515+
return "'" + escapeString(sb.toString()) + "'";
477516
} else if (x instanceof InputStream) {
478517
StringBuilder sb = new StringBuilder();
479518
InputStream is = (InputStream) x;
@@ -482,13 +521,17 @@ private static String encodeObject(Object x) throws SQLException {
482521
while ((len = is.read(buffer)) != -1) {
483522
sb.append(new String(buffer, 0, len));
484523
}
485-
return "'" + sb + "'";
524+
return "'" + escapeString(sb.toString()) + "'";
486525
}
487526

488-
return x.toString();
527+
return escapeString(x.toString());//Escape single quotes
489528
} catch (Exception e) {
490529
LOG.error("Error encoding object", e);
491530
throw new SQLException("Error encoding object", e);
492531
}
493532
}
533+
534+
private static String escapeString(String x) {
535+
return x.replace("'", "''");//Escape single quotes
536+
}
494537
}

0 commit comments

Comments
 (0)