diff --git a/pom.xml b/pom.xml
index 73ffe765b..2efed71a0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -65,6 +65,7 @@
1.15.1
6.14.3
1.10.19
+ 2.27.2
3.2.0
3.0.0-M1
1.6.8
@@ -151,6 +152,12 @@
${mockito.version}
test
+
+ com.github.tomakehurst
+ wiremock-jre8
+ ${wiremock.version}
+ test
+
diff --git a/src/main/java/ru/yandex/clickhouse/ClickHouseConnectionImpl.java b/src/main/java/ru/yandex/clickhouse/ClickHouseConnectionImpl.java
index d5edba5ae..e767bd445 100644
--- a/src/main/java/ru/yandex/clickhouse/ClickHouseConnectionImpl.java
+++ b/src/main/java/ru/yandex/clickhouse/ClickHouseConnectionImpl.java
@@ -111,7 +111,13 @@ public ClickHouseStatement createStatement() throws SQLException {
}
public ClickHouseStatement createStatement(int resultSetType) throws SQLException {
- return LogProxy.wrap(ClickHouseStatement.class, new ClickHouseStatementImpl(httpclient, this, properties, resultSetType));
+ return LogProxy.wrap(
+ ClickHouseStatement.class,
+ new ClickHouseStatementImpl(
+ httpclient,
+ this,
+ properties,
+ resultSetType));
}
@Deprecated
@@ -126,15 +132,37 @@ public TimeZone getTimeZone() {
}
private ClickHouseStatement createClickHouseStatement(CloseableHttpClient httpClient) throws SQLException {
- return LogProxy.wrap(ClickHouseStatement.class, new ClickHouseStatementImpl(httpClient, this, properties, DEFAULT_RESULTSET_TYPE));
+ return LogProxy.wrap(
+ ClickHouseStatement.class,
+ new ClickHouseStatementImpl(
+ httpClient,
+ this,
+ properties,
+ DEFAULT_RESULTSET_TYPE));
}
public PreparedStatement createPreparedStatement(String sql, int resultSetType) throws SQLException {
- return LogProxy.wrap(PreparedStatement.class, new ClickHousePreparedStatementImpl(httpclient, this, properties, sql, getTimeZone(), resultSetType));
+ return LogProxy.wrap(
+ PreparedStatement.class,
+ new ClickHousePreparedStatementImpl(
+ httpclient,
+ this,
+ properties,
+ sql,
+ getTimeZone(),
+ resultSetType));
}
public ClickHousePreparedStatement createClickHousePreparedStatement(String sql, int resultSetType) throws SQLException {
- return LogProxy.wrap(ClickHousePreparedStatement.class, new ClickHousePreparedStatementImpl(httpclient, this, properties, sql, getTimeZone(), resultSetType));
+ return LogProxy.wrap(
+ ClickHousePreparedStatement.class,
+ new ClickHousePreparedStatementImpl(
+ httpclient,
+ this,
+ properties,
+ sql,
+ getTimeZone(),
+ resultSetType));
}
@@ -408,12 +436,13 @@ public boolean isValid(int timeout) throws SQLException {
return false;
} finally {
- if (isAnotherHttpClient)
+ if (isAnotherHttpClient) {
try {
closeableHttpClient.close();
} catch (IOException e) {
log.warn("Can't close a http client", e);
}
+ }
}
}
@@ -462,22 +491,27 @@ public boolean isWrapperFor(Class> iface) throws SQLException {
return iface.isAssignableFrom(getClass());
}
+ @Override
public void setSchema(String schema) throws SQLException {
properties.setDatabase(schema);
}
+ @Override
public String getSchema() throws SQLException {
return properties.getDatabase();
}
+ @Override
public void abort(Executor executor) throws SQLException {
this.close();
}
+ @Override
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
}
+ @Override
public int getNetworkTimeout() throws SQLException {
return 0;
}
diff --git a/src/main/java/ru/yandex/clickhouse/ClickHousePreparedStatementImpl.java b/src/main/java/ru/yandex/clickhouse/ClickHousePreparedStatementImpl.java
index e5e1fae0c..bd4cf4cb6 100644
--- a/src/main/java/ru/yandex/clickhouse/ClickHousePreparedStatementImpl.java
+++ b/src/main/java/ru/yandex/clickhouse/ClickHousePreparedStatementImpl.java
@@ -1,26 +1,48 @@
package ru.yandex.clickhouse;
-import org.apache.http.entity.AbstractHttpEntity;
-import org.apache.http.impl.client.CloseableHttpClient;
-import ru.yandex.clickhouse.response.ClickHouseResponse;
-import ru.yandex.clickhouse.settings.ClickHouseProperties;
-import ru.yandex.clickhouse.settings.ClickHouseQueryParam;
-import ru.yandex.clickhouse.util.ClickHouseArrayUtil;
-import ru.yandex.clickhouse.util.ClickHouseValueFormatter;
-import ru.yandex.clickhouse.util.guava.StreamUtils;
-
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
import java.sql.Date;
-import java.sql.*;
-import java.util.*;
+import java.sql.NClob;
+import java.sql.ParameterMetaData;
+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.SQLSyntaxErrorException;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.http.entity.AbstractHttpEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+
+import ru.yandex.clickhouse.response.ClickHouseResponse;
+import ru.yandex.clickhouse.settings.ClickHouseProperties;
+import ru.yandex.clickhouse.settings.ClickHouseQueryParam;
+import ru.yandex.clickhouse.util.ClickHouseArrayUtil;
+import ru.yandex.clickhouse.util.ClickHouseValueFormatter;
+import ru.yandex.clickhouse.util.guava.StreamUtils;
+
public class ClickHousePreparedStatementImpl extends ClickHouseStatementImpl implements ClickHousePreparedStatement {
@@ -36,11 +58,11 @@ public class ClickHousePreparedStatementImpl extends ClickHouseStatementImpl imp
private final ClickHousePreparedStatementParameter[] binds;
private final List> parameterList;
private final boolean insertBatchMode;
- private List batchRows = new ArrayList();
+ private List batchRows = new ArrayList<>();
- public ClickHousePreparedStatementImpl(CloseableHttpClient client, ClickHouseConnection connection,
- ClickHouseProperties properties, String sql, TimeZone serverTimeZone,
- int resultSetType) throws SQLException
+ public ClickHousePreparedStatementImpl(CloseableHttpClient client,
+ ClickHouseConnection connection, ClickHouseProperties properties, String sql,
+ TimeZone serverTimeZone, int resultSetType) throws SQLException
{
super(client, connection, properties, resultSetType);
this.sql = sql;
@@ -295,7 +317,7 @@ public void addBatch() throws SQLException {
private List buildBatch() throws SQLException {
checkBinded();
- List newBatches = new ArrayList(parameterList.size());
+ List newBatches = new ArrayList<>(parameterList.size());
StringBuilder sb = new StringBuilder();
for (int i = 0, p = 0; i < parameterList.size(); i++) {
List pList = parameterList.get(i);
@@ -338,7 +360,7 @@ public int[] executeBatch(Map additionalDBParams)
sendStream(entity, insertSql, additionalDBParams);
int[] result = new int[batchRows.size()];
Arrays.fill(result, 1);
- batchRows = new ArrayList();
+ batchRows = new ArrayList<>();
return result;
}
diff --git a/src/main/java/ru/yandex/clickhouse/ClickHouseStatementImpl.java b/src/main/java/ru/yandex/clickhouse/ClickHouseStatementImpl.java
index 19bcc402a..89c10a556 100644
--- a/src/main/java/ru/yandex/clickhouse/ClickHouseStatementImpl.java
+++ b/src/main/java/ru/yandex/clickhouse/ClickHouseStatementImpl.java
@@ -1,12 +1,28 @@
package ru.yandex.clickhouse;
-import com.google.common.base.Strings;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.UUID;
+
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
@@ -16,35 +32,34 @@
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Strings;
+
import ru.yandex.clickhouse.domain.ClickHouseFormat;
import ru.yandex.clickhouse.except.ClickHouseException;
import ru.yandex.clickhouse.except.ClickHouseExceptionSpecifier;
-import ru.yandex.clickhouse.response.*;
+import ru.yandex.clickhouse.response.ClickHouseLZ4Stream;
+import ru.yandex.clickhouse.response.ClickHouseResponse;
+import ru.yandex.clickhouse.response.ClickHouseResponseSummary;
+import ru.yandex.clickhouse.response.ClickHouseResultSet;
+import ru.yandex.clickhouse.response.ClickHouseScrollableResultSet;
+import ru.yandex.clickhouse.response.FastByteArrayOutputStream;
import ru.yandex.clickhouse.settings.ClickHouseProperties;
import ru.yandex.clickhouse.settings.ClickHouseQueryParam;
+import ru.yandex.clickhouse.util.ClickHouseHttpClientBuilder;
import ru.yandex.clickhouse.util.ClickHouseRowBinaryInputStream;
import ru.yandex.clickhouse.util.ClickHouseStreamCallback;
import ru.yandex.clickhouse.util.Utils;
import ru.yandex.clickhouse.util.guava.StreamUtils;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.util.*;
-
-
public class ClickHouseStatementImpl extends ConfigurableApi implements ClickHouseStatement {
private static final Logger log = LoggerFactory.getLogger(ClickHouseStatementImpl.class);
private final CloseableHttpClient client;
+ private final HttpClientContext httpContext;
+
protected ClickHouseProperties properties;
private ClickHouseConnection connection;
@@ -79,10 +94,12 @@ public class ClickHouseStatementImpl extends ConfigurableApi(ClickHouseQueryParam.class);
+ additionalDBParams = new EnumMap<>(ClickHouseQueryParam.class);
} else {
- additionalDBParams = new EnumMap(additionalDBParams);
+ additionalDBParams = new EnumMap<>(additionalDBParams);
}
additionalDBParams.put(ClickHouseQueryParam.EXTREMES, "0");
@@ -621,7 +638,7 @@ private InputStream getInputStream(
HttpPost post = new HttpPost(uri);
post.setEntity(requestEntity);
- HttpResponse response = client.execute(post);
+ HttpResponse response = client.execute(post, httpContext);
entity = response.getEntity();
checkForErrorAndThrow(entity, response);
@@ -687,7 +704,7 @@ private List getUrlQueryParams(
Map additionalRequestParams,
boolean ignoreDatabase
) {
- List result = new ArrayList();
+ List result = new ArrayList<>();
if (sql != null) {
result.add(new BasicNameValuePair("query", sql));
@@ -755,17 +772,21 @@ private boolean isQueryParamSet(ClickHouseQueryParam param, Map additionalClickHouseDBParams, Map additionalRequestParams) {
- if (additionalRequestParams != null && additionalRequestParams.containsKey(param.getKey()) && !Strings.isNullOrEmpty(additionalRequestParams.get(param.getKey())))
+ if (additionalRequestParams != null && additionalRequestParams.containsKey(param.getKey()) && !Strings.isNullOrEmpty(additionalRequestParams.get(param.getKey()))) {
return additionalRequestParams.get(param.getKey());
+ }
- if (getRequestParams().containsKey(param.getKey()) && !Strings.isNullOrEmpty(getRequestParams().get(param.getKey())))
+ if (getRequestParams().containsKey(param.getKey()) && !Strings.isNullOrEmpty(getRequestParams().get(param.getKey()))) {
return getRequestParams().get(param.getKey());
+ }
- if (additionalClickHouseDBParams != null && additionalClickHouseDBParams.containsKey(param) && !Strings.isNullOrEmpty(additionalClickHouseDBParams.get(param)))
+ if (additionalClickHouseDBParams != null && additionalClickHouseDBParams.containsKey(param) && !Strings.isNullOrEmpty(additionalClickHouseDBParams.get(param))) {
return additionalClickHouseDBParams.get(param);
+ }
- if (getAdditionalDBParams().containsKey(param) && !Strings.isNullOrEmpty(getAdditionalDBParams().get(param)))
+ if (getAdditionalDBParams().containsKey(param) && !Strings.isNullOrEmpty(getAdditionalDBParams().get(param))) {
return getAdditionalDBParams().get(param);
+ }
return properties.asProperties().getProperty(param.getKey());
}
@@ -775,7 +796,7 @@ private URI followRedirects(URI uri) throws IOException, URISyntaxException {
int redirects = 0;
while (redirects < properties.getMaxRedirects()) {
HttpGet httpGet = new HttpGet(uri);
- HttpResponse response = client.execute(httpGet);
+ HttpResponse response = client.execute(httpGet, httpContext);
if (response.getStatusLine().getStatusCode() == 307) {
uri = new URI(response.getHeaders("Location")[0].getValue());
redirects++;
@@ -896,7 +917,7 @@ void sendStream(Writer writer, HttpEntity content) throws ClickHouseException {
httpPost.addHeader("Content-Encoding", writer.getCompression().name());
}
httpPost.setEntity(content);
- HttpResponse response = client.execute(httpPost);
+ HttpResponse response = client.execute(httpPost, httpContext);
entity = response.getEntity();
checkForErrorAndThrow(entity, response);
@@ -932,10 +953,12 @@ private void checkForErrorAndThrow(HttpEntity entity, HttpResponse response) thr
}
}
+ @Override
public void closeOnCompletion() throws SQLException {
closeOnCompletion = true;
}
+ @Override
public boolean isCloseOnCompletion() throws SQLException {
return closeOnCompletion;
}
diff --git a/src/main/java/ru/yandex/clickhouse/settings/ClickHouseProperties.java b/src/main/java/ru/yandex/clickhouse/settings/ClickHouseProperties.java
index 14ce0774f..b368917e9 100644
--- a/src/main/java/ru/yandex/clickhouse/settings/ClickHouseProperties.java
+++ b/src/main/java/ru/yandex/clickhouse/settings/ClickHouseProperties.java
@@ -1,11 +1,11 @@
package ru.yandex.clickhouse.settings;
-import ru.yandex.clickhouse.util.apache.StringUtils;
-
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
+import ru.yandex.clickhouse.util.apache.StringUtils;
+
public class ClickHouseProperties {
@@ -302,22 +302,42 @@ public ClickHouseProperties(ClickHouseProperties properties) {
}
public Map buildQueryParams(boolean ignoreDatabase){
- Map params = new HashMap();
+ Map params = new HashMap<>();
- if (maxParallelReplicas != null) params.put(ClickHouseQueryParam.MAX_PARALLEL_REPLICAS, String.valueOf(maxParallelReplicas));
- if (maxPartitionsPerInsertBlock != null) params.put(ClickHouseQueryParam.MAX_PARTITIONS_PER_INSERT_BLOCK, String.valueOf(maxPartitionsPerInsertBlock));
- if (maxRowsToGroupBy != null) params.put(ClickHouseQueryParam.MAX_ROWS_TO_GROUP_BY, String.valueOf(maxRowsToGroupBy));
- if (totalsMode != null) params.put(ClickHouseQueryParam.TOTALS_MODE, totalsMode);
- if (quotaKey != null) params.put(ClickHouseQueryParam.QUOTA_KEY, quotaKey);
- if (priority != null) params.put(ClickHouseQueryParam.PRIORITY, String.valueOf(priority));
+ if (maxParallelReplicas != null) {
+ params.put(ClickHouseQueryParam.MAX_PARALLEL_REPLICAS, String.valueOf(maxParallelReplicas));
+ }
+ if (maxPartitionsPerInsertBlock != null) {
+ params.put(ClickHouseQueryParam.MAX_PARTITIONS_PER_INSERT_BLOCK, String.valueOf(maxPartitionsPerInsertBlock));
+ }
+ if (maxRowsToGroupBy != null) {
+ params.put(ClickHouseQueryParam.MAX_ROWS_TO_GROUP_BY, String.valueOf(maxRowsToGroupBy));
+ }
+ if (totalsMode != null) {
+ params.put(ClickHouseQueryParam.TOTALS_MODE, totalsMode);
+ }
+ if (quotaKey != null) {
+ params.put(ClickHouseQueryParam.QUOTA_KEY, quotaKey);
+ }
+ if (priority != null) {
+ params.put(ClickHouseQueryParam.PRIORITY, String.valueOf(priority));
+ }
- if (!StringUtils.isBlank(database) && !ignoreDatabase) params.put(ClickHouseQueryParam.DATABASE, getDatabase());
+ if (!StringUtils.isBlank(database) && !ignoreDatabase) {
+ params.put(ClickHouseQueryParam.DATABASE, getDatabase());
+ }
- if (compress) params.put(ClickHouseQueryParam.COMPRESS, "1");
- if (decompress) params.put(ClickHouseQueryParam.DECOMPRESS, "1");
+ if (compress) {
+ params.put(ClickHouseQueryParam.COMPRESS, "1");
+ }
+ if (decompress) {
+ params.put(ClickHouseQueryParam.DECOMPRESS, "1");
+ }
- if (extremes) params.put(ClickHouseQueryParam.EXTREMES, "1");
+ if (extremes) {
+ params.put(ClickHouseQueryParam.EXTREMES, "1");
+ }
if (StringUtils.isBlank(profile)) {
if (getMaxThreads() != null) {
@@ -336,13 +356,16 @@ public Map buildQueryParams(boolean ignoreDatabase
params.put(ClickHouseQueryParam.PROFILE, profile);
}
- if (user != null) params.put(ClickHouseQueryParam.USER, user);
- if (password != null) params.put(ClickHouseQueryParam.PASSWORD, password);
-
- if (distributedAggregationMemoryEfficient) params.put(ClickHouseQueryParam.DISTRIBUTED_AGGREGATION_MEMORY_EFFICIENT, "1");
+ if (distributedAggregationMemoryEfficient) {
+ params.put(ClickHouseQueryParam.DISTRIBUTED_AGGREGATION_MEMORY_EFFICIENT, "1");
+ }
- if (maxBytesBeforeExternalGroupBy != null) params.put(ClickHouseQueryParam.MAX_BYTES_BEFORE_EXTERNAL_GROUP_BY, String.valueOf(maxBytesBeforeExternalGroupBy));
- if (maxBytesBeforeExternalSort != null) params.put(ClickHouseQueryParam.MAX_BYTES_BEFORE_EXTERNAL_SORT, String.valueOf(maxBytesBeforeExternalSort));
+ if (maxBytesBeforeExternalGroupBy != null) {
+ params.put(ClickHouseQueryParam.MAX_BYTES_BEFORE_EXTERNAL_GROUP_BY, String.valueOf(maxBytesBeforeExternalGroupBy));
+ }
+ if (maxBytesBeforeExternalSort != null) {
+ params.put(ClickHouseQueryParam.MAX_BYTES_BEFORE_EXTERNAL_SORT, String.valueOf(maxBytesBeforeExternalSort));
+ }
if (maxMemoryUsage != null) {
params.put(ClickHouseQueryParam.MAX_MEMORY_USAGE, String.valueOf(maxMemoryUsage));
}
@@ -421,8 +444,9 @@ private T getSetting(Properties info, ClickHouseConnectionSettings settings)
@SuppressWarnings("unchecked")
private T getSetting(Properties info, String key, Object defaultValue, Class clazz){
String val = info.getProperty(key);
- if (val == null)
+ if (val == null) {
return (T)defaultValue;
+ }
if (clazz == int.class || clazz == Integer.class) {
return (T) clazz.cast(Integer.valueOf(val));
}
@@ -974,16 +998,18 @@ public Properties getProperties() {
public ClickHouseProperties merge(ClickHouseProperties second){
Properties properties = this.asProperties();
- for (Map.Entry