Skip to content

Commit

Permalink
Merge pull request #1965 from ClickHouse/Adjusting-jdbc
Browse files Browse the repository at this point in the history
Adding types, adjusting constructors
  • Loading branch information
Paultagoras authored Nov 23, 2024
2 parents 4c02535 + 094d238 commit 27f8a3d
Show file tree
Hide file tree
Showing 12 changed files with 201 additions and 138 deletions.
46 changes: 34 additions & 12 deletions jdbc-v2/src/main/java/com/clickhouse/jdbc/ConnectionImpl.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
package com.clickhouse.jdbc;

import com.clickhouse.client.api.Client;
import com.clickhouse.client.api.data_formats.ClickHouseBinaryFormatReader;
import com.clickhouse.client.api.query.GenericRecord;
import com.clickhouse.client.api.query.QueryResponse;
import com.clickhouse.client.api.query.QuerySettings;
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.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;

public class ConnectionImpl implements Connection, JdbcV2Wrapper {
private static final Logger log = LoggerFactory.getLogger(ConnectionImpl.class);
Expand Down Expand Up @@ -47,7 +47,6 @@ public ConnectionImpl(String url, Properties info) {
.setPassword(config.getPassword())
.setClientName(clientName)
.build();

this.defaultQuerySettings = new QuerySettings();
}

Expand Down Expand Up @@ -166,8 +165,8 @@ public DatabaseMetaData getMetaData() throws SQLException {
@Override
public void setReadOnly(boolean readOnly) throws SQLException {
checkOpen();
if (!readOnly) {
throw new SQLFeatureNotSupportedException("read-only=false unsupported");
if (readOnly) {
throw new SQLFeatureNotSupportedException("read-only=true unsupported");
}
}

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

@Override
public void setClientInfo(String name, String value) throws SQLClientInfoException {
throw new SQLClientInfoException("ClientInfo not supported", null);
// 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"));
}

@Override
public void setClientInfo(Properties properties) throws SQLClientInfoException {
throw new SQLClientInfoException("ClientInfo not supported", null);
// 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"));
}

@Override
public String getClientInfo(String name) throws SQLException {
checkOpen();
return null;
// Object value = this.defaultQuerySettings.getAllSettings().get(name);
// return value == null ? null : String.valueOf(value);
throw new SQLFeatureNotSupportedException("getClientInfo not supported");
}

@Override
public Properties getClientInfo() throws SQLException {
checkOpen();
return new Properties();
// Properties clientInfo = new Properties();
// clientInfo.putAll(this.defaultQuerySettings.getAllSettings());
// return clientInfo;
throw new SQLFeatureNotSupportedException("getClientInfo not supported");
}

@Override
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
//TODO: Should this be supported?
return null;
try {
return new com.clickhouse.jdbc.types.Array(List.of(elements));
} catch (Exception e) {
throw new SQLException("Failed to create array", e);
}
}

@Override
Expand Down
18 changes: 9 additions & 9 deletions jdbc-v2/src/main/java/com/clickhouse/jdbc/DataSourceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
import java.util.logging.Logger;

public class DataSourceImpl implements DataSource, JdbcV2Wrapper {
private static final Logger log = Logger.getLogger(DataSourceImpl.class.getName());
private String url;
private Properties info;
private Driver driver;
private final Driver driver;
private PrintWriter logWriter;

public void setUrl(String url) {
this.url = url;
Expand All @@ -24,22 +26,20 @@ private Properties getProperties() {
copy.putAll(info);
return copy;
}

public void setProperties(Properties info) {
this.info = info;
}

public DataSourceImpl() {

public DataSourceImpl() {//No-arg constructor required by the standard
this(null, new Properties());
}

public DataSourceImpl(String url) {
this(url, new Properties());
}

public DataSourceImpl(String url, Properties info) {
this.url = url;
this.info = info;
this.driver = new Driver();
this.driver = new Driver(this);
}

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

@Override
public PrintWriter getLogWriter() throws SQLException {
throw new SQLFeatureNotSupportedException("Method not supported");
return logWriter;
}

@Override
public void setLogWriter(PrintWriter out) throws SQLException {
throw new SQLFeatureNotSupportedException("Method not supported");
logWriter = out;
}

@Override
Expand Down
28 changes: 23 additions & 5 deletions jdbc-v2/src/main/java/com/clickhouse/jdbc/Driver.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
package com.clickhouse.jdbc;

import java.sql.*;
import java.util.*;

import com.clickhouse.jdbc.internal.JdbcConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;

/**
* JDBC driver for ClickHouse.
*/
public class Driver implements java.sql.Driver {
private static final Logger log = LoggerFactory.getLogger(Driver.class);
public static final String driverVersion;
private final DataSourceImpl dataSource;

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

public Driver() {
this.dataSource = null;
}

public Driver(DataSourceImpl dataSourceImpl) {
this.dataSource = dataSourceImpl;
}

public static void load() {
try {
DriverManager.registerDriver(new Driver());
Expand All @@ -74,6 +92,9 @@ public static void unload() {

@Override
public Connection connect(String url, Properties info) throws SQLException {
if (!acceptsURL(url)) {
return null;
}
return new ConnectionImpl(url, info);
}

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

@Override
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
// if (!JdbcConfiguration.acceptsURL(url)) {
// return new DriverPropertyInfo[0];
// }
return new DriverPropertyInfo[0];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,25 @@
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.*;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.JDBCType;
import java.sql.NClob;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLType;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
Expand All @@ -16,6 +34,7 @@
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Calendar;
import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.Map;

Expand Down Expand Up @@ -439,7 +458,7 @@ private static String encodeObject(Object x) throws SQLException {
if (x == null) {
return "NULL";
} else if (x instanceof String) {
return "'" + x + "'";
return "'" + escapeString((String) x) + "'";
} else if (x instanceof Boolean) {
return (Boolean) x ? "1" : "0";
} else if (x instanceof Date) {
Expand All @@ -454,8 +473,28 @@ private static String encodeObject(Object x) throws SQLException {
return "'" + DATETIME_FORMATTER.format(((Timestamp) x).toLocalDateTime()) + "'";
} else if (x instanceof LocalDateTime) {
return "'" + DATETIME_FORMATTER.format((LocalDateTime) x) + "'";
} else if (x instanceof Array) {
StringBuilder listString = new StringBuilder();
listString.append("[");
for (Object item : (Object[])((Array) x).getArray()) {
listString.append(encodeObject(item)).append(", ");
}
listString.delete(listString.length() - 2, listString.length());
listString.append("]");

return listString.toString();
} else if (x instanceof Collection) {
StringBuilder listString = new StringBuilder();
listString.append("[");
for (Object item : (Collection<?>) x) {
listString.append(encodeObject(item)).append(", ");
}
listString.delete(listString.length() - 2, listString.length());
listString.append("]");

return listString.toString();
} else if (x instanceof Map) {
Map tmpMap = (Map) x;
Map<?, ?> tmpMap = (Map<?, ?>) x;
StringBuilder mapString = new StringBuilder();
mapString.append("{");
for (Object key : tmpMap.keySet()) {
Expand All @@ -473,7 +512,7 @@ private static String encodeObject(Object x) throws SQLException {
while ((len = reader.read(buffer)) != -1) {
sb.append(buffer, 0, len);
}
return "'" + sb + "'";
return "'" + escapeString(sb.toString()) + "'";
} else if (x instanceof InputStream) {
StringBuilder sb = new StringBuilder();
InputStream is = (InputStream) x;
Expand All @@ -482,13 +521,17 @@ private static String encodeObject(Object x) throws SQLException {
while ((len = is.read(buffer)) != -1) {
sb.append(new String(buffer, 0, len));
}
return "'" + sb + "'";
return "'" + escapeString(sb.toString()) + "'";
}

return x.toString();
return escapeString(x.toString());//Escape single quotes
} catch (Exception e) {
LOG.error("Error encoding object", e);
throw new SQLException("Error encoding object", e);
}
}

private static String escapeString(String x) {
return x.replace("'", "''");//Escape single quotes
}
}
Loading

0 comments on commit 27f8a3d

Please sign in to comment.